[erlang-questions] Changing the shell and module syntax and semantics

Thu Mar 8 23:05:35 CET 2007

On 8 Mar 2007, at 9:30 pm, Joe Armstrong wrote:
> I Talked to Dave Thomas (Prag P) - he said "why can't you type
> everything into the shell"
> I said bla bla bla .., any explained how it is
> He said - but it must be easy to implement ....
> Having slept on it I think he's right.
> Why not?

Let's see:  we have a "module language" which accepts declarations  
and ONLY declarations,
and we have a "shell language" which accepts expressions and ONLY  

Sounds right to me.  That's exactly the way Haskell interpreters  
work, and I have to say that in about
6 years of teaching Haskell, this is one "feature" of Haskell that  
students DON'T have any trouble with.

A particular point is that the shell is expected to give a response  
after EVERY "sentence",
but thanks to the preprocessor, there are constructs in the module  
language that contain
many "sentences".

> all we need to do is add an invisible "-module(shell)" to
> the session, remember all the stuff that's typed in and
> as new functions come either compile the complete module (so far)
> or interpret the code.

It really is not that easy, not at all.  The closest analogue would  
be SML, where the interactive
"shell" CAN accept declarations as well as expressions.
     f% sml
     Standard ML of New Jersey v110.55 [built: Fri Oct 14 14:48:17 2005]
     - fun f x = 1 + x;
     val f = fn : int -> int
     - f 42;
     val it = 43 : int
     - [it,it,it];
     val it = [43,43,43] : int list

Strictly speaking, in the SML interactive top level, an expression  
counts as a definition for 'it'.
And this brings me to the key point.  The SML shell allows you to  
REdefine identifiers without
any fuss.  And this is consistent with the rest of the language,  
which also allows you to
redefine identifiers without any fuss, because SML has strict lexical  
scoping combined with
strict declaration-before-use (except as modified by letrec).  If in  
an SML module you write
	fun f x = x + 1;
	... code using f ...
	fun f x = x - 1;
	... more code using f ...
what you have done is not to CHANGE the old f, but to HIDE it; the  
scope of the second definition
is nested inside the scope of the first.  And the code using f uses  
the definition it could see, not the
new definition.
	fun f x = x + 1;
	fun g x = f (x * 2);
	fun f x = x - 1;
	fun h x = f (x * 2);
	g 27
  =>	55
	h 27
  =>	53

Now the scope of Erlang functions just plain does not work like that.

> In fact these is no good reason not to allow this in modules as  
> well ...
> -module(mmm).
> X = 12 + lists:sqrt(23).
> foo(A) ->
>      A + X.
> .... etc....

I like the notation, but I wonder what the semantics is.  Erlang  
*function* declarations do not have
to be in any particular order, but Erlang *variable* bindings do.   
What happens if I have

	X = foo(12).

	foo(Y) -> X + Y.

in a module?  Module *parameters* avoid this problem.

These changes would be a nice idea if/when the semantic problems were  

More information about the erlang-questions mailing list