[erlang-questions] some language changes

Thu May 24 08:28:29 CEST 2007

Joe Armstrong wrote:
 > What you type in the shell and what you type in a module/escript
 > should be the same.

Currently they aren't.  The shell has something the module language
does not, and that is the ability to bind a top-level variable.  It
is a great pity that the module language requires you to write

     -define(CORNERS, 4).
     ... ?CORNERS ...

instead of a plain

     Corners = 4.
     ... Corners ...

The module language has something the shell does not, namely the
ability to define named mutually recursive functions.  (Also the
ability to define records, but the sooner that wart in the language
is replaced by a decent data structure like Joe's "proper structs"/
IBM Prolog "items"/my "frames" -- which are all pretty much identical)
the better.)

I wrote:
 > This has never been the case in Smalltalk, and nobody seems to
 > notice any problem.

That judgement was based on several years of subscription to a
Smalltalk mailing list with overwhelming traffic, in which many
issues were raised, but never ever that one, and on my own use of
Smalltalk, in which it was just never something you wanted to do,
because a browser was just a keypress away.

On 24 May 2007, at 2:20 am, Mike Berrow wrote:
> I've used Smalltalk and I've been making a living programming in Ruby
> for the last 18 months. Now that you point that out, it is one of the
> large advantages that Ruby has over Smalltalk w.r.t
> experimentation / prototyping / learning curve

Of course much depends on the Smalltalk system you are using, and
whether someone explains it to you properly.  You *can't* type in
class definitions and method definitions in a Workspace (= shell),
but you *can* type in arbitrary expressions while editing a method
and evaluate them.  Indeed, it is common (and recommended) practice
to include examples as comments in methods.  For example, we might have

       "#(3 1 4 1 5) bind: [:x | |s|
         s := x asSet.
         (x allSatisfy: [:e | s includes: e]) and: [
         (s allSatisfy: [:e | x includes: e]]]"
       r := Set new: self size.
       self do: [:each | r add: each].

The code between double quotes is actually a comment.  Put the cursor
just to the right of the opening one or just to the left of the closing
one.  Double click.  Type Cmd-p.  The editor inserts ' true' (the value
of the expression), highlighted so Delete will remove it.  Basically,
the pane in which one edits a method IS a Workspace, amongst other
What this tells us is that you can put the shell functionality in
a module editor instead of doing it the other way around.

>> It has never been the case in Prolog.
>> ....
> Is Erlang tied to Prolog in this?  If not, why does that matter?

No.  Surely it is obvious that I was giving a series of examples in
which the module language and the shell language are different, and
it really isn't a problem.  I also gave the example of Haskell, which
Erlang is obvious not "tied to".

What *can* be a big problem (and in several years of work with Lisp
I ran into this more times than I care to remember) is typing
definitions in at a "shell" and ending up with a state you *want* to
preserve but isn't recoverable from any source files.  (Interlisp
dealt with this by decreeing that 'source' files were actually
databases, so that practically any state *could* be dumped as legible
code, except that macros meant it didn't really work all that well.)

>> And that's a really important point.  Joe is suggesting that
>> the Erlang shell should be changed to make it easier for beginners
>> to shoot themselves in the foot, instead of learning practices that
>> will help to keep them out of trouble.  I cannot think that a good  
>> idea.
> I've found the transparency between the interactive shell and source
> environments in Ruby to be nothing but a huge boost in productivity.
> I've never had this "shooting myself in the foot" effect because of  
> it.
> If there is something intrinsically different about the Erlang  
> world that
> makes it dangerous, I would appreciate it if you could elaborate.

I literally cannot believe that this would be a HUGE boost in
productivity.  I think we are in agreement that TRYING THINGS OUT
is a help.  What we do not agree about is that this has to be done
by merging module language features into the shell, rather than by
merging shell features into the module language.

I've done a fair bit of stuff in R, an open source clone of the well
respected and widely used statistics language S.  In S and R the
shell language and the module language are identical.  There are a
number of things that save you.  One is that when you type
    f <- function (...) { ... }
in response to the prompt, R saves the full source text, so that if
you later do
    f <- edit(f)
it will work.  (Unless you told R not to save full source text, in
which case you are left swearing at yourself for a fool.  This is the
"shooting yourself in the foot" case.)  The other is that you can
dump any R data structure to a file, including functions, and you can
also dump the entire state of the R system to a file.  Indeed, when
you quit it normally offers to do this for you.  (S keeps most of your
state in files anyway.)

The Smalltalk systems I am used to keep a log of everything you have
typed in the .changes file, so that if the worst comes to the worst
and you trash your working image beyond belief you can fire up a fresh
copy of the system and recover changes from this log.

Erlang doesn't do that.  Erlang also doesn't offer a way to save the
complete state of a node to a file (not that I know of).

There is one thing about the shell that I would like to change, and
it is a minor change, which would bring Erlang into line with Haskell
and Lisp and Prolog, and would make trying things out in the shell
easier without major ramifications.  That is the ability to set a
current module and, in effect, evaluate expressions INSIDE some module.
This is how Hugs works, for example.  The interactive shell is always
inside some module, typically the last one loaded but you can change it
to whatever you want.  Expressions you type are interpreted in the
scope of that module.

Suppose you are working on a module under some editor.
(I am sure I remember being able to run 'erl -x' to get something
like this.  Whatever happened to that?  What is the right command?)
For the sake of concreteness, suppose it is Emacs.

You have one window at the top, editing the module.
You have another window at the bottom, running the shell.
Type a query in the shell.  It doesn't work.
A single chord gets you to the other window.
Make a change.
Again, a single chord should save the change, silently rerun the
compiler, silently reload the module (if the compilation worked),
and take you back to the shell window.
Another chord should replay the query.
Conversely, find an interesting expression in the module window,
possibly inside a comment.  Select it.  A single chord ships it
invisibly to the shell and the result appears there.
Where I have said "chord", you can bind the effect to a single
function key if you like.

With an interface like that, you get all the convenience of trying
things out WITHOUT any change to the shell language or module language
at all.  It is difficult to believe that eliminating at most two
keystrokes per definition could be a HUGE productivity boost.

More information about the erlang-questions mailing list