[E-Lang] Syntax change: reducing side-effects

Marc Stiegler marcs@skyhunter.com
Sun, 11 Feb 2001 16:38:15 -0700


Dean,

On a completely different tangent from the point you were making, are you
proposing this multiple-closure on-a-line style for E? As in

}   }   }   }   }

My first reaction was shock, my second was, this really does have some
charms, notably being able to see more actual code on the page, and in fact
making it easier to look at and confirm that you have lined up and closed
the whole nested structure (at least at the end of an objectMaker
definition). The biggest disadvantage I see is that it will look alien to
the Java programmers we are trying to lure into E by making it look "just
like Java".

Anyway, I haven't thought it through, so I'm asking in case you have :-)

--marcs

----- Original Message -----
From: Dean Tribble <tribble@e-dean.com>
To: <e-lang@eros-os.org>
Sent: Sunday, February 11, 2001 3:38 PM
Subject: [E-Lang] Syntax change: reducing side-effects


> In the current E language, any name can be assigned unless it is specified
> as :final.  As is the case with most good programming, however, most names
> only ever get one value at initialization time, and programmers typically
> assume that they always have that value.  For example, when you see
'define
> MintMaker(name) :any {' in the MintMaker program, you ought to be able to
> assume that the value of the 'MintMaker' binding won't change over
> time!  But in the current language, it could perfectly well be assigned
> somewhere later in the module, and then even references to it internal to
> its code would refer unknowingly to the new MintMaker.  A similar case can
> be made for most arguments, pattern variables, and even local
> variables.  Assignment is the fundamental source of race conditions and
> other non-local dependencies in software systems.
>
> To address this problem, I have the following proposal (with help from
> MarkM and Marcs):
>
> We should change the syntax (in as painless a way as possible) so it is
> statically apparent at name definition time whether a variable could be
> assigned.
>
> Corollary: Assignments can only be made to names that are statically
> declared as assignable.  All other names are pure, immutable bindings.
>
> We went through various unacceptable alternatives which I will summarize
if
> the discussion warrants it.  Here I will just propose the one that
actually
> appears to just work, and has various other unifying effects on the
syntax.
>
> Summary: all defining occurrences of names now default to 'final', unless
> they are prefixed by 'var', in which case they are settable.  In addition,
> 'var' can be used as a top-level construct as an alternative to 'define'
> (equivalent to 'define var').
>
> In detail:
>
> - This change applies to all defining occurrences of bindings ('define',
> patterns, argument to methods, etc.)
>
> - Reserve the new keyword, 'var'.
>
> - For defining occurrence without the 'var' keyword, the guard is always
> and only a ValueGuard.  If absent, the guard defaults to the ValueGuard,
> ':any'.  It can be translated into Kernel E as always being wrapped with a
> 'final' SlotMaker.  The compiler must statically reject assignments to
> names defined without 'var'.
>
> - For defining occurrences that are prefixed with the 'var' keyword, the
> guard is always a SlotGuard.  If absent, it defaults to ':settable'.
>
> - User-defined SlotGuards can only be used with a 'var' prefix.  As a
> result, the reader of the code (including a compiler) is guaranteed that
> unless there is a 'var' prefix, the value of the variable will only ever
be
> the initial value (i.e., user-defined SlotGuards can allow assignments).
>
> - 'var' as the top-level keyword for an expression is equivalent to
'define
> var'.
>
> Below are a few examples.  The only change to MintMaker is in the argument
> to makePurse which declares the 'balance' instance variable.
>
> define MintMaker(name) :any {
>      define [sealer, unsealer] := BrandMaker pair(name)
>      define mint {
>          to printOn(out) { out print(`<$name's mint>`) }
>          to makePurse(var balance : (any >= 0)) :any {
>              define decr(amount : (0..balance)) {
>                  balance -= amount
>              }
>              define purse {
>                  to printOn(out)    { out print(`<has $balance $name
bucks>`) }
>                  to getBalance :any { balance }
>                  to sprout     :any { mint makePurse(0) }
>                  to getDecr    :any { sealer seal(decr) }
>                  to deposit(amount : integer, src) {
>                      unsealer unseal(src getDecr)(amount)
>                      balance += amount
> }   }   }   }   }
>
> (Note that *I* collapsed the braces to one line :-).
>
> The result, however, is that the programmer can know that all the other
> names (like 'purse', 'mint', 'sealer', etc.) are *in fact* defined once
and
> never change, just like they automatically assume, albeit sometimes
> painfully incorrectly.  Just for the heck of it, I counted the number of
> changes required in the code in "E in a Walnut" for this change, and there
> were about 10 'var' declarations required.  Most were as in the example
> below where they declare mutable instance variables.  The others were in
> loops that accumulate things.
>
> def carMaker new(name) :any {
>      var xLocation := 0
>      var yLocation := 0
>      def car {
>          to moveTo(x,y) {
>              xLocation := x
>              yLocation := y
>          }
>          to getX :any {xLocation}
>          to getY :any {yLocation}
>          to getName :any {name}
>      }
> }
>
> The result, however, was that the 100+ other uses of 'def' in the document
> correctly supported the programmers assumption of immutability!
>
> The other big consequence of this is that interpreter and compiler can use
> that information for substantial performance improvement for the by-far
> typical case of no assignment.
>
> Comments?
> dean
>
> _______________________________________________
> e-lang mailing list
> e-lang@mail.eros-os.org
> http://www.eros-os.org/mailman/listinfo/e-lang
>