1,393 karma · joined August 13, 2010
As of today (2/3/2016), this account is now 2000 days old with 1369 karma. I've decided to celebrate by announcing a switch to a (for better or worse) far-less-anonymous account, "pmarreck".
The biggest hurdles I had coming from OO Ruby were 1) how to handle state, since you no longer can just hang information off any arbitrary object attributes, 2) pattern matching (but now that I grok it, I love it, it's so useful and leads to more concise code), 3) lack of inheritance (although oddly, I don't seem to miss it, it just leads to a somewhat different code design), 4) OTP semantics (which after you mount the learning curve, make a lot of sense from a resiliency standpoint).
There are a number of neat little details not yet mentioned or emphasized here such as full Unicode support, full-fledged macros that give you full AST access (in a non-homoiconic language, that is a rarity!), custom sigils (http://elixir-lang.org/getting-started/sigils.html), the ability to easily call into any Erlang library, the fantastic :observer.start() utility for visually observing tons of details about a running pid hierarchy, etc.
One possible hurdle unique to languages that feature message passing between independent processes (pids or process id's) as a core feature is that once you have a pid hierarchy, it seems to me that inevitably, one of them will get a backlog of messages requiring you to either apply back-pressure techniques (slowing down upstream synchronous messaging by slowing down replies, basically) or pursue some other strategy (code refactoring etc.) when messages start to get discarded under load due to overflowing the pid inbox.
This would weight code refactors with the weight they deserve...
"My pragmatic summary: A large fraction of the flaws in software development are due to programmers not fully understanding all the possible states their code may execute in. (Emphasis mine. That alone explains most of the bugs I've seen.) In a multithreaded environment, the lack of understanding and the resulting problems are greatly amplified, almost to the point of panic if you are paying attention. Programming in a functional style makes the state presented to your code explicit, which makes it much easier to reason about, and, in a completely pure system, makes thread race conditions impossible...
"No matter what language you work in, programming in a functional style provides benefits. You should do it whenever it is convenient, and you should think hard about the decision when it isn't convenient."
This is a man who has coded slightly longer than I have, and IMHO he is correct on all these points.
I merely believe he didn't go far enough (for example, immutable "variables", which are not available in OO languages without hairy workarounds, ENSURE that the state your code "sees" is not tampered with "from the outside," further reducing bugs), but statements like this are why I take the viewpoint I do.
Take the amount of time you debug as a percentage of your total programming time (and hell, we all enjoy debugging to a degree, don't we? But what's debugging, really? All it is, is trying to discover a state that wasn't conceived of when the code was designed, no? That's the whole point of your stack trace, right?). Now, chop that time in half. Would you want this? Who wouldn't?
Yes, FP is not appropriate for all realms where code lives. But it should most certainly fill all the spaces it currently does not, where its appropriateness is not out of the question.
I would also strongly recommend the "Are We There Yet?" talk by Rich Hickey http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic... which pretty much destroys mutability as a language-level trait, pretty much rendering it the mother of all bugs (literally).
Again, don't take my word for it- here is MIT's core CS curriculum on mutability's dangers: http://web.mit.edu/6.005/www/fa15/classes/09-immutability/
Have I made a strong argument yet, now?
This is why I get upset whenever a new language comes out that does not feature FP/immutable paradigms. If you're new, you SHOULD be using these, otherwise you're just perpetuating more man-years of debugging hell for people. I am tired of watching new programmers make the same mistakes over and over and over again.
The very length of this comment alone indicates how hard it is to communicate this AND why it sounds like preaching/proselytizing/trolling.
Those are really the limiting factors, I think.
In other words, it is extremely naive (and quite unfair to infringers) to assume that EVERY pirated copy of something is a lost sale. The folks I've known who pirate are more like... data hoarders than payment evaders... Oftentimes they never even bothered consuming the media, it was all about collecting things first for them, and they would have never paid for said media to begin with, so it really becomes nebulous to start swinging around accusations of theft, because... what was "stolen"? Some unknown percentage of the copies surely ARE lost sales, but how can we determine that percentage? Would it vary based on attributes of the media?
In any event, I think the entire state of China would probably be the worst copyright offender, if they're looking for someone to go after...
Dude, that right there is the problem. They make a commission off your starting salary, so OF COURSE their primary concern is your past and future financials.
This is why I hate recruiters.
I find an interesting parallel between 1/2/4/8 repeating beats/parts in songs, and binary...
But any perusal of rosettacode.org is fairly indicative that other languages, while less mature, have adopted some good ideas.
For example, here's Quicksort in both Java and Elixir:
public static <E extends Comparable<? super E>> List<E> quickSort(List<E> arr) {
if (!arr.isEmpty()) {
E pivot = arr.get(0); //This pivot can change to get faster results
List<E> less = new LinkedList<E>();
List<E> pivotList = new LinkedList<E>();
List<E> more = new LinkedList<E>();
// Partition
for (E i: arr) {
if (i.compareTo(pivot) < 0)
less.add(i);
else if (i.compareTo(pivot) > 0)
more.add(i);
else
pivotList.add(i);
}
// Recursively sort sublists
less = quickSort(less);
more = quickSort(more);
// Concatenate results
less.addAll(pivotList);
less.addAll(more);
return less;
}
return arr;
}
now Elixir: defmodule QuickSort do
def qsort([]) do
[]
end
def qsort([pivot | rest]) do
{ left, right } = Enum.partition(rest, fn(x) -> x < pivot end)
qsort(left) ++ [pivot] ++ qsort(right)
end
end
The advantage here is NOT just an "economy of typing."I also suspect that people would rather not know your phallus size or six+ figure income. All these things are left to discover as a side effect of normal interactions ;)
http://www.forbes.com/sites/jacquelynsmith/2013/03/08/the-pr...
I think this is the actual study?
http://www.nerisearch.com/neri-newsletter-career-development...
Basically, a skilled employee gets the most out of a job in the first 3 years. And the new company gets the most out of the employee in the first 3 years (or so). After that, in order to restart the learning experience for both parties, a "change of venue" is necessary.