Admittedly, I don't have any metrics on how many people have abandoned Erlang because of single assignment, or Lisp because of the parentheses, but I'm sure such people exist.
And you might say that it's their loss, and I'd probably agree with you.
Admittedly, I don't have any metrics on how many people have abandoned Erlang because of single assignment, or Lisp because of the parentheses, but I'm sure such people exist.
And you might say that it's their loss, and I'd probably agree with you.
Enough people give up, though, and it's your loss as a user of that language. Say out of every 100 people that give up, 1 is someone who is capable of contributing something good back, and 10 are people who might have answered questions on mailing lists or IRC, or written some blog entries or something. Languages do have network effects.
Were that language design so simple ...
I meant more along the lines of libraries to do useful things, which is a win pretty much any way you look at it.
Indeed I would say that. But there's another side. When a language allows for slippage in conceptual integrity for the sake of familiarity, everyone loses.
For example, I'm a big fan of Ruby, but there a number of places where consistency in language axioms was dropped so as to supposedly make it more intuitive. It does so at the cost of everyone having to remember both the fundamental concepts (e.g., "the last expression evaluated in a method is the return value") and the exceptions ("except when the method name ends with '=').
Lazy people like me think that's just extra work. :)
I don't know Erlang, but I suspect that if some form of "multiple assignment that isn't really the multiple assignment you're used to" were allowed, people would still have problems with it, but they would be harder to understand and resolve based on core language principals.
Erlang has a pretty simple binding compared to, say, ML. In the statement
X = Expr, Body
Evaluates Expr, binds it to X and evaluates the body with X bound. This is akin to variants of let-bindings found in so many other languages. The difference is, however, that the binding can not be shadowed. If body contains, say:
X = Expr2,
it is taken as an assertion: Evaluate Expr2 and compare it to X, crashing the program if Expr2 is not equal to (in effect) Expr. What some miss is that this is not mutation, but binding. In
X = 0, F = fun (Y) -> Y + X end, X = 1, F(4).
The X inside the body of F is bound to 0 and not 1 when F gets evaluated because any semantics apart from this would be silly in a functional language with lexical scope. And since Erlang has no concept of Let-bound scopes in functions it would probably give some of the problems you mention.
I guess the Prolog-history plays a part in the decision, but also the fact that explicit (single) assignment is a really good tool for weeding out bugs: Any use will explicitly refer to exactly one def. Several compilers that allow shadowing of let-scopes even go as far as including a warning when you shadow variables!