Syntax q's

Craig Dickson crd@REDACTED
Tue Nov 2 16:33:50 CET 1999


A couple of things have been irritating me a little with Erlang's syntax. I
was wondering if anyone else agreed with my views of these (quite limited)
cases, and if so, what the best forum and format would be for proposing
minor syntactical extensions.

*****

First, in a function head, to bind a record argument to a variable, and also
perform pattern-matching on its fields, you have to say:

    f(R)
        when ... R#rtype.field1 ..., ... R#rtype.field2 ... ->

which isn't bad, except that it would be convenient to also bind those
fields to variables at the same time. The first time I wanted to do this, it
seemed intuitively obvious to me that the following should work, but it
doesn't:

    f(R#rtype{field1 = Var1, field2 = Var2})
        when ... Var1 ..., ... Var2 ... ->

I guess, in essence, what I'm saying is that there are three things Erlang
will let you do with a record argument in a function head: (1) bind it, as a
whole, to a variable (R above), (2) pattern-match on its fields (the guards
in the first example), and (3) bind its fields to variables (as in the
second example). I would like to do all of these things simultaneously, but
Erlang won't let me; it will only let me have any two of the three in any
given function head.

Does anyone else think that Erlang should allow all three at once?

*****

My other complaint is that the standard libraries have functions that take
module and function atoms (e.g. apply/3), but which cannot take funs. For
example, I would like to be able to experiment with timer:tc/3 in the Erlang
shell by just declaring a fun interactively and calling tc like this:

    F = fun(...) -> ... end.
    timer:tc(F, [args...]).

But this isn't possible because tc doesn't take a fun. I suppose this is a
historical artifact, since funs are a relatively recent addition to the
language. Still, it would be nice to allow funs to be used more universally.

I would even like apply/3 to be able to take a fun, like this:

    apply(F, Args) when function(F), list(Args) ->

because this would provide for a sort of built-in uncurrying capability that
would make it trivially easy to pass around a fun and its list of arguments
in a tuple, and evaluate them in contexts that might not have any idea how
many arguments the fun took. For example:

    apply_list(L) when list(L) ->
        lists:map(fun({F,A}) when function(F), list(A) -> F(A) end, L).

Here L is a list of {Fun, ArgList} pairs, where the arity of each Fun
corresponds to the length of its ArgList.

Of course, the same effect can be achieved on an ad-hoc basis by wrapping
each fun in another fun that takes a list of known length and breaks it up,
e.g.:

    fun(F, [A,B,C]) -> F(A, B, C) end.

But it seems to me that this shouldn't be necessary. Does anyone else agree?

Craig





More information about the erlang-questions mailing list