[E-Lang] down with 'define'

Mark S. Miller markm@caplet.com
Tue, 06 Mar 2001 15:05:54 -0800


At 07:25 AM Tuesday 3/6/01, Ralph Hartley wrote:
>I think there are "pure" declarative languages that are religious about it, but I don't remember using any.

Well, Dean paged a whole bunch of memories back in when he reminded me that 
Joule has this property.  So I have my concrete example.


>Certainly lisp (at least traditional dialects) has no need for forward declarations, and it is an expression based language (like E). Of course, those dialects don't have any type checking to speak of either.

Although in most ways I dearly love Scheme, both Lisp and Scheme are 
disasters in this regard, and were motivating counter-examples for me in 
designing E.  I'll just use Scheme below since it's simpler and cleaner.

Scheme has at least the following scoping constructs for binding a name to 
the value of an expression, and having that name be in scope over some 
expression

let, let*, letrec, rec, define

Although a Scheme program is a simple S-Expression tree structure, if you 
drew scope boxes over these trees for each of these constructs, you'd find 
there was no general rule you could state.  Each of these constructs has its 
own rule, and the only general statements you can make happen after 
expanding all these.

So for all it's problems, E's rule "point of introduction till end of scope 
box" is a wonder of uniformity compared to this otherwise god-like language.


>Top level classes are required to be in separate files, so ordering between them is not defined, but classes local to another class don't care about order.

I believe this last is where there's a substantive difference between Java 
and E.  Java's named nested and inner classes correspond to E's object 
definitions.  To all you Java programmers: If named nested and inner classes 
required forward references in order to be mutually recursive, how bad would 
that be? 

>The reason java cares about order for variables, is that declaration is conflated with initialization. In Java variables are initialized where they are declared, and all variables must be initialized ("int i;" contains a default initialization to 0). Your second example above is not so much an undefined variable, as an uninitialized one (though the compiler may claim otherwise).
>
>Variables are an exception in java to the rule that the scope starts at the "{".
>
>>Order is space, not time, and is about scoping, not sequence of execution.  
>>[...] I believe we are instead arguing about something like whether the applicable scope starts at the point of introduction or at the previous open curly.
>
>Correct.

Ok, I have a concrete proposal to put on the table:

Make E scopes truly order independent, in the way Joule's are.  If a 
defining occurrence of "foo" appears anywhere in the top level of a scope 
box (that is, in the scope box but not in a nested scope box), the any use 
of "foo" anywhere in that scope box (including nested scope boxes that don't 
shadow "foo") corresponds to that defining occurrence.

Of course, like Joule, E isn't in the bind you point out above that Java 
would be were it to make this decision.  If the variable is used before its 
initialized its value is a promise for what it will be initialized to.  Once 
it's initialized, all these promises resolve to this initial value.

This proposal makes me queasy, but it's simpler than what we've got, and I 
don't actually see anything wrong with it yet.


>Without [a decent module system] no one will even consider E for any but the smallest projects. This is far more of a "Check box" item than inheritance, and with good reason.

I agree.  This is very important.  I'm glad you raised it.


>Is definition in E really assignment? That is is
>
>startofblock
>def foo fi[r]stdef
>... uses foo ... (firstdef is used)
>def foo seconddef
>... uses foo ... (seconddef is used)
>endofblock
>
>legal?

For reasons we can ignore for now, it is legal in one place -- the top level 
interactive environment.  Outside this context, it is not legal.  A name can 
only be defined once in a scope.  Definition is not assignment.  Were 
it not for the familiarity issue, it would have been better for it not to 
look like assignment.


        Cheers,
        --MarkM