[erlang-questions] Erlang and syntax.

Richard A. O'Keefe <>
Tue Feb 25 02:36:22 CET 2014

On 25/02/2014, at 12:38 PM, Siraaj Khandkar wrote:
> I fail to see the ugliness in:
>  let dot xs ys =
>    let rec loop = function
>      | x::xs, y::ys, s -> loop (xs, ys, s + x * y)
>      |     _,     _, s -> s
>    in
>    loop (xs, ys, 0)

F# syntax is based on CAML.
CAML syntax is based on an early revision of ML
before the major cleanup that produced SML.
(Not unlike the way C perpetuated a blunder
that had already been fixed in its ancestor BCPL.)

Already in this example it shows up.
There are two functions.
They have to be declared differently.

There are two kinds of lambda expression:

	fun Pat+ [when Guard] -> Expr

may have multiple *arguments* but not multiple *clauses*,

	function [|] Pat [when Guard] -> Expr
               {  |  Pat [when Guard] -> Expr }...

may have multiple *clauses* but not multiple *arguments*.

The calls to loop have parentheses around the arguments
(to make a tuple, because a function with multiple clauses
can't have multiple arguments), but the pattern matches
_don't_ have the parentheses.  By the way, tuples-without-
parentheses are why O'CAML has to use semicolons to
separate list elements, unlike practically everything else
where commas are used.

The outer function 'dot' is declared using a let-binding
	value_name {parameter}... = expr
which allows multiple *arguments* but not multiple
*clauses*, which is why the inner function 'loop'
*has* to use a lambda-expression.

In contrast, here's the same thing in SML.

fun dot xs ys =
    let fun loop (x::xs) (y::ys) s = loop xs ys (s+x*y)
          | loop _       _       s = s
     in loop xs ys 0

In SML, functions can have BOTH multiple arguments and
multiple clauses.

>> Does anyone else remember my proposal that would have had us
>> write this as
>>   dot(Xs, Ys) ->
>>     (S where S = 0 then S+X*Y || X <- Xs & Y <- Ys).
> Where is S coming from here?

From the 'where' part.  It's
   ( <result> where <binding>,... || <generators and tests> )
and a <binding> is
   <pattern> = <initial value> [then <subsequent value>].

'let P = E0 in E1' and 'E1 where P = E0' are traditional
alternatives in functional programming.

It's a cross between Lisp's DO (the <binding> part and the
<result> part) and comprehensions (the <generators and tests> part).

More information about the erlang-questions mailing list