[erlang-questions] Core Erlang questions

Lars-Åke Fredlund <>
Thu Oct 16 13:31:58 CEST 2008

Richard Carlsson wrote:
> Lars-Åke Fredlund wrote:
>>  From reading the Core Erlang 1.0.3 language specification it seems that
>> it is impossible to have expressions with "complex subexpressions" (a 
>> very nice syntactic property!)
>> For example,
>>    the tuple
>>            {2, receive <X> when 'true' -> X after 'infinity' -> 'true'}
>>    would not be legal Core Erlang since the receive (like any other 
>> expression)
>>    returns a sequence, not a value. And because it is not a value,
>>   such a sequence cannot be "spliced" into a tuple (except via an outer 
>> let expression):
>>  let <_cor1> =
>>            receive
>>              <X> when 'true' ->
>>                  X
>>            after 'infinity' ->
>>              'true'
>>        in
>>            {2,_cor1}
>> Is this a correct understanding of the dynamic semantics? (or is a 
>> singleton sequence also a value?)
>> How should one then understand the "2" in the tuple, doesn't this 
>> expression also return a sequence?
> No no, don't worry, you can nest expressions as much as you like.
> Grammatically, page 7 shows how an Expression 'e' can be either a
> SingleExpression 's' or a ValueList '< s1, ..., sN >' of zero or more
> SingleExpressions. A SingleExpression is an "ordinary, plain expression"
> like an atom, a tuple, a fun, a case switch, etc. The arguments to
> these (such as the elements of a tuple) are in their turn also
> Expressions.
> Page 11 explains (or tries to) that in Core Erlang, every expression
> evaluates to a sequence of zero or more values, whereas in plain Erlang,
> an expression always evaluates to exactly one value. Sequences have no
> runtime representation in themselves, so you cannot pass them around
> or nest them. A sequence '<x>' is usually written 'x' where there is
> no risk of confusion.
> For the dynamic semantics ("what does it _mean_"), first, Page 13 states
> that expressions used as arguments to other expressions (e.g., an
> element of a tuple) is expected to always evaluate to a sequence of
> exactly one element, i.e., you cannot return multiple values if you are
> going to use the result as a direct argument - for that, you do need a
> let-binding or similar to access the different values. But the main
> thing (which is not very obvious), is that you need to read the
> evaluation rules for expressions (section 6.3) carefully if you want to
> see how the transition between "values" and "sequences" is specified.
> For example, evaluation of a tuple is described like this:
>  "{e_1, ..., e_n}
>   This evaluates to the Erlang n-tuple {x_1, ...,x_n}, where for i in
>   [1,n], e_i evaluates to x_i. ..."
> Here, "e_i evaluates to x_i" really means "e_i evaluates to <x_i>"
> (that's the "no risk of confusion" part above), so e.g. in your
> example, the '2' evaluates to '<2>', from which the rule takes the
> naked value 2 and uses it to construct <{2,...}>.
> (In my original specification drafts, I used a downcast operator
> everywhere to move explicitly from seqences to naked values, but
> it turned out messy and unreadable. Switching to a more implicit
> specification, I got something that is much more readable but
> perhaps harder for a semanticist to follow to the point, at least
> without a guide.)
>     /Richard
> PS. It was hard to write, so by Zeus, it should be hard to read!
Thank you for the explanation, which made the definition much more clearer.

Anyway I  wasn't worrying, I was rather hoping :-) that it was 
impossible to have very
"complicated" expressions. In a sense having a very simple input format 
where "computation" (calling functions, receive, case, etc) of 
expressions only takes place in let arguments, and the let body only 
composes basic values and variables using simple data constructors. The  
Core Erlang output from compile:file (with option 'to_core') seems (in 
my limited testing experience) to respect this.

Essentially I want to implement a transformation lifting a subexpression 
with a receive out from its expression context, and if that receive 
expression can occur at an arbitrary depth the task will be a bit harder 
(not much, but a bit). Anyway, the separation between returning a value 
and variable binding
enforced in Core Erlang (through the requirement to a sequence of one 
element) will help.


More information about the erlang-questions mailing list