[erlang-questions] Funargs: Ruby-like blocks for Erlang

Richard O'Keefe ok@REDACTED
Fri Jul 22 05:35:07 CEST 2011


On 22/07/2011, at 2:19 PM, Tony Arcieri wrote:
> Here are some strategies to delimiting tokens that make sense to me:
> 
> "{" ... "}" - the oft reviled curly brace approach. These are a paired set of tokens that match.

Who reviles it?  Nobody in Erlang.  We use those for tuples.
(And SETL uses them for sets, and Smalltalk uses them for arrays, and ...)
> 
> "beginningtoken" ... "endingtoken" - these match at least in that they're words, and perhaps their meaning describes how they represent the beginning and end of a block of code

Hey, I'm an Ada fan.
> 
> "->" ... "." - these don't do a great job of matching up

AND IN ERLANG NOBODY EVER DREAMED THAT THEY MIGHT BE THOUGHT OF AS MATCHING UP.
They do not.

Consider

	max(X, Y) when X >= Y -> X;
	max(X, Y) when X <  Y -> Y.

Think of ";" as an infix operator:

	『max(X, Y) when X >= Y -> X』
	;
	『max(X, Y) when X <  Y -> Y』.

I've put the corner brackets in to show clearly what the "operands" of ";" are.
You will notice that the "->" tokens are INSIDE the corner brackets.
There is no sense whatever in which they can be said to match the ".".
The "." is outside the corner brackets.
NO token matches it.

Now think of "when" and "->" as infix operators.

	『『『max(X, Y)』 when 『X >= Y』』 -> 『X』』
	;
	『『『max(X, Y)』 when 『X <  Y』』-> 『Y』』.

"when", "->", and ";" look like infix operators and in many ways act
like infix operators.  They can certainly be parsed as infix operators.
NONE of these three tokens "matches" any other token, EVER.
Not "." and not "end".

One hypothesis occurs to me, and that is that you have formed a mental model
of Erlang based on functions and funs with only one clause, where you might
see a parallel between 
	[](int x, int y) { return x + y; }	// C++
	 ^(int x, int y) { return x + y; }	// Objective C
	fun (  X,     Y) ->       X + Y  end

and think that "fun" is like "[]" or "^", "->" is like "{",
and "end" (or ".") is like "}".

But that is a false analogy which breaks down horribly when you have
multiple clauses.  If it's not your analogy, my apologies, but it is
the only way I can imagine someone coming up with the crazy idea
that "->" *ever* matches "end" or ".".

> Now compare this to:
> 
> "->" ... "end"
> 
> Seriously. WTF is that?

It is a radical misunderstanding of Erlang syntax, that's what it is.
There is *NO* syntactic unit in Erlang *anywhere* that has the
form "->" ... "end".   None.

> Those two tokens do not match up whatsoever.
> 
> The "->" token, elsewhere in Erlang, is found in "forms", which are statements in that they do not return a value.

Wrong.  There are no "forms" in Erlang which do not return values.
"if", "case", "receive", and "try" are *ALL* of them *expressions*
with well defined values.

It's true that in C/C++/ObjC/JavaScript/Java/C# "if" and "case" and "try"
are statements.  So much the worse for them.  Erlang is not any of those
languages.  (If you want to compare it with any imperative language, try
Algol 68, in which also "if" and "case" were expressions, not statements.)

Come to think of it, according to
http://www.ruby-doc.org/docs/ProgrammingRuby/
the "if" construct in Ruby is also an expression, it returns a value,
and so does "case".

> They define functions and can't be used from things which only comprehend Erlang expressions, such as eshell.
> 
> The "end" token, elsewhere in Erlang, is only found in expressions, like "case", "if", "receive", and "try". Expressions return a value.

"funs" are no exception.
The pattern that is common to all of them is

	<opening keyword> <head> '->' <body> {';' <head> '->' <body>}... 'end'

There is nothing whatsoever exceptional about funs in this regard.





More information about the erlang-questions mailing list