[erlang-questions] Funargs: Ruby-like blocks for Erlang
Joe Armstrong
erlang@REDACTED
Fri Jul 22 09:55:08 CEST 2011
On Fri, Jul 22, 2011 at 6:28 AM, Richard O'Keefe <ok@REDACTED> wrote:
>
> On 22/07/2011, at 3:49 PM, Tony Arcieri wrote:
>
>> On Thu, Jul 21, 2011 at 7:43 PM, Richard O'Keefe <ok@REDACTED> wrote:
>> Wrong. In funs, "end" is paired with "fun" and "fun" ONLY.
>>
>> Okay, conceded (and Jachym made the same point)
>>
>> I'll revert to my other point, which is that the '->' token in Erlang is only found in forms outside of funs, which are expressions. No other expression in Erlang uses the '->' token.
>
> I am totally confused here.
> Erlang constructs "->" if and only if they have patterns-and-guards
> (well, patterns-and-or-guards, to be picky) to separate from bodies.
>
> That's it. No exceptions.
>
> I have just revised the Expressions chapter of the reference manual,
> and I cannot find one single example of a kind of expression that
> _should_ use "->" but doesn't.
>
> So what kind of expression do _you_ think ought to use "->" but doesn't?
>
>> I'd also ask what you feel about the people who responded to this thread
>> who find the Erlang fun syntax awkward. I certainly find it awkward.
>
> Oh dear, this is going to sound insulting, but it's not meant that way.
>
> I am more impressed by people who demonstrate that they understand how
> the current syntax actually *works* before they complain about it.
>
> I myself have said that I find Erlang syntax "clunky but tasteful".
> It uses more tokens than Haskell does.
>
> But then, Haskell syntax is surprisingly tricky, and I'm not sure
> how many Haskell parsers actually get it 100% right.
>
> For reference, it took a huge amount of fighting in the ISO Prolog
> committee to agree on an unambiguous syntax, and in the revision mailing
> list there are continuing, um, strong disagreements. I think the
> restrictions compared with classic Prolog were and are too severe. But
> a correspondent who has done a heck of a lot more work on standards issues
> in recent years than I have points out with a great deal of justice that
> the various Prolog implementations out there STILL don't agree on syntax,
> not as much as their authors fondly imagine. He'd like to see them get
> what's in the standard right before adding anything else.
>
> Do not despise a simple syntax that implementors can actually get RIGHT.
>
> It is *HARD* to come up with a clean coherent syntax for the whole of a
> programming language. And it is triply hard to patch your way there,
> and outright impossible to do it by adding inconsistencies.
>
> Yes, "fun ... end" is not as pretty as it could be, but for something
> that was added years after Erlang was shipping, it's nearly as close
> to the rest of the language as anyone could wish for. (The thing I
> don't like is the scope rules for variables shared between "fun" heads
> and their contexts, which has nothing to do with keywords or
> punctuation.)
>
> If you don't like funs in Erlang, try Objective C or JavaScript for a while.
Now you've set me off ...
If you think Erlang funs are problematic you should take a look
at javascript. Javascript closures are truly horrible
NOTE in what follows "$$" means the javascript shell prompt
$$ x = 10;
10
Now let's make a function y that adds x to its argument
Pretty simply, eh,
In Erlang I'd write fun(Y) -> Y + X end
In Javascript I write:
$$ f = function(y){return(x+y);};
function (y){return(x+y);}
Test it:
$$ f(5);
15
Hooray - great - but wait a moment
Now change x
$$ x=20;
20
Now if the force was with javascript I'd rather hope that
I had not accidentally broken f. What happens?
Now what was f(5), let's take a look:
$$ f(5);
25
Oh dear - maths is broken. f(5) is not what it was earlier
Try again:
$$ x = 10;
10
Add an extra level of indirection and throw in some semicolons
$$ f = (function(z){return function(y){return y+z;};})(x);
(( F = fun(Y) -> Y + X end, in Erlang :-))
function (y){return y+z}
$$ f(5);
15
So far so good.
Now lets change x
$$ x=20;
20
Have we broken f?
$$ f(5);
15
No f still works.
No Lets' go back to Erlang and repeat the argument as it were.
Let's pretent Erlang is javascript
> X = 10;
> F = fun(Y) -> X + Y end;
Now ask the javascript question "what happens if I now change X"
Erlang answer - you can't
Now if you think horrible incantations like
f = (function(z){return function(y){return y+z;};})(x);
in Javascript solved all your problems with closures think again. What you
do inside the {...} bits of a function depends crucially on the semantics
of assignment in javascript.
I have three javascript books at home - I looked up assignment in all three.
But none of them said anything sensible ...
What does
x = y;
mean in javascript?
If I say
x = y;
In javascript and then change y, is x changed? Or if I change x is
y changed.
Is x a deep or shallow copy of y - well the answer is of course "it depends"
Now in Erlang X = Y behaves as if you'd made a deep copy of Y.
Of course you don't actually make a deep copy of Y - you just think you have,
and the question "what happens to X if we subsequently change Y?" is
easy to answer "You can't change Y"
(actually - non of the three Erlang books mention this, if you come
from javascript
you have to worry about the semantics of assignment, and the deep and
shallow copying implied by assignment)
Erlang fun syntax might have the odd wart (variable bindings can sometimes
seem strange to the unaccustomed eye) but at least things bound in closures
are actually bound in the closure and cannot be changed later - this
means no nasty surprises later.
Cheers
/Joe
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
More information about the erlang-questions
mailing list