[E-Lang] stl-0.8.9k: Syntax Changes

Mark S. Miller markm@caplet.com
Mon, 22 Jan 2001 16:38:28 -0800


At 06:25 AM Sunday 1/21/01, Tyler Close wrote:
>Markm wrote:
>>     def _ (a :(any < 7), _) :(any > 3) { ... a ... }
>
>So...
>
>        def foo() :any { ... }
>
>Means foo() returns an object of unspecified type.
>
>        def foo() :integer { ... }
>
>Means foo() returns an object of type integer.
>
>        def foo() :(any > 3) { ... }
>
>Means foo() return an object of unspecified type greater than 3, so
>does this parse:
>
>        def foo() :(integer > 3) { ... }
>
>If so, is it the same as:
>
>        def foo() :(integer & any > 3) { ... }

Yes.  In fact, :(any > 3) is the same as well, since the meaning is 
"anything greater than 3", which necessarily only includes things comparable 
to three.  With this meaning in mind, "any" effectively picks up the type 
from its operand.  Since this isn't at all obvious, I like your form better.

At 12:58 AM Monday 1/22/01, Tyler Close wrote:
>Markm wrote:
>>     def _ (a :(any < 7), _) :(any > 3) { ... a ... }
>
>Is it possible to construct a grammar where there is nothing at all in
>place of both the '_' and the 'any'? So that you could write:
>
>        def (a :( < 7 ), ) :( > 3 ) { ... }
>
>It seems clear to me that the above expression can be unambiguously
>parsed, but I don't have much experience writing language grammars.

I don't know if it's possible either, but it probably is, and I could check 
easily enough. (yacc is wonderful that way.)  However, I dislike this form 
for a reason related to why I like your ":(integer > 3)" better than my 
":(any > 3)".  Because E's operators are just syntactic sugar for messages, 
"any" is implemented in E with no special privilege.  However, as long as 
there's only one "any", big deal.  As your ":(integer > 3)" example makes 
clear, when one designs a type, such as integer, one can also design a 
protocol for restricting the values accepted, or whatever, and bundle it 
into that type, according to a protocol that may be specific to that type.  
This extensibility and uniformity is much more valuable than the extra 
characters saved.


>If that's not possible, then I would be happy using the variable name.
>
>        def anon(a :( a < 7 ), ignored) :( anon > 3 ) { ... }

Doesn't work at all because it has a conflicting interpretation: The second 
"a" is a use occurrence in the scope of the first "a" as defining 
occurrence.  Therefore it refers to the value of the slot bound to the first 
"a".  What slot?  Why that made my the value of "a < 7" when sent the 
makeSlot message.  Sure this is circular, but such cycles are meaningful in 
E.  It should result in the second "a", at the time of evaluation, being 
bound to a promise that would resolve after the first "a" has been bound.  
Since "a < 7" expands to an immediate call, this will throw an exception 
complaining about an immediate call on an eventual reference.

(Note: the above code is rejected by the current implementation with a "not 
implemented yet".  This is a bug.)


        Cheers,
        --MarkM