[e-lang] A thought experiment: Minimal-E
Mark Miller
erights at gmail.com
Wed Jul 5 20:29:14 EDT 2006
I like this notion of defining a Minimal-E, as a way of defining much
of the semantics of Kernel-E in terms of further expansions. Do you
suggest any operational role for Minimal-E (as opposed to Kernel-E)?
Since reflection (e.g., by audting or 'meta.context().getSource()')
does reveal the expansion to Kernel-E, these equivalences, and any
others, are only "operationally equivalent up to reflection". I have
seen some other language use similar weasel words for the same reason.
Further, many of these expansions break a single object up into
several objects, e.g., by repackaging an internal block as a closure.
This changes the semantics of constructs that are sensitive to the
placement of object boundaries, such as the 'meta...' expressions, as
well as garbage collection obligations: In a given computational
state, what is considered reachable? If we consider weak pointers to
be a kind of reflective operation, we can include all these within the
same weasel words "operationally equivalent up to reflection".
One possible operational use I can see is for an auditor to first
expand its ObjectExpr to Minimal-E to reduce the number of cases it
needs to care about. Even though this might transform nested
ObjectExprs in such a way that they would no longer pass their
auditors, this auditor needn't care about that, since those other
auditors will only see the un-transformed versions of their
ObjectExprs.
On 7/2/06, Kevin Reid <kpreid at mac.com> wrote:
> AssignExpr
>
> a := b
> def r__1 := b; &a.setValue(r__1); r__1
* Doesn't preserve left-to-right scoping - would get confused if the
'b' expression defined an 'a' variable.
* As in C, postfix operators including "." bind tighter than prefix
operators, so you need to say '(&a).setValue(r__1)'.
Putting these together, expand e`a := b` to
e`(&a).setValue(def r__1 := b); r__1`
> CatchExpr
>
> try { a } catch b { c }
> __Mcatch(fn { a }, fn b { c })
There is already some experimental support in E-on-Java for something
along these lines.
To enable experimentation with user defined control constructs,
pragma.enable("lambda-args")
enables the productions
call: ... // normal choices
| control;
control: call '(' argList ')' sepWord paramList body
| prim 'fn' paramList body
| control sepWord paramList body
| control sepWord '(' argList ')' body;
sepWord: 'catch' | 'else' | 'escape' | 'finally' | 'guards' | 'in'
| 'thunk' | 'fn' | 'try' | '->' | Ident | reserved;
Note that these productions are *not* part of the official E grammar.
With this enabled,
__try fn{ a } catch b { c }
expands to
__try.fn__control_0(fn{a}).catch__control_1(fn b {c}).run__control()
This expansion generates a mangled verb name as
'<sepWord>__control__<arity-info>'.
It generates one message per clause of the original control construct,
in order to accumulate
all the clauses as closures. Finally, once they are all accumulated,
the expansion ends by
saying '.run__control()' in order to cause the accumulated control
construct to run.
The corresponding implementation of __try.emaker is attached.
Neither Kevin's __Mcatch nor the attached __try can itself be
implemented in Minimal-E. In order for try-catch to not be a special
form in Minimal-E, either __Mcatch or __try would need to be a
primitive object. Nevertheless, this is interesting, as primitive
objects arguably add less weight to the language than special forms.
For example, a maximally absorbing meta-circular interpreter needs to
mention all special forms, but not primitive objects.
The above expansions are much more disciplined than even hygenic
macros. In particular, they enforce E's scoping rules no matter what
the logic is of the control abstraction being invoked.
I will revisit this way of supporting user-defined control constructs
in responding to Constantine's recent posts.
[out of order]
> EscapeExpr
>
> escape a { b } catch c { d }
> __Mescape("a", fn a { b }, fn c { d })
>
> FinallyExpr
>
> try { a } finally { b }
> __Mfinally(fn { a }, fn { b })
>
> IfExpr
>
> if (a) { b } else { c }
> __Mif({[a, fn { b }]}, fn { c })
Similar comments apply as for the CatchExpr. The corresponding
__escape.emaker and __if.emaker files, and other similar experiments,
can be found in
e/src/esrc/org/erights/e/elang/control/*.emaker
> CdrPattern
>
> [a] + b
> via (__Mcdr(1)) [a, b]
Yes, E-on-Java 0.8.37a already does essentially this during expansion
to Kernel-E. As of that version, CdrPattern is no longer part of
Kernel-E.
? epatt`[a] + b`
# value: epatt`via (__splitList.run(1)) [a, b]`
> FinalPattern
>
> a
> via (__Mfinal) &a
> VarPattern
>
> var x
> via (__MvarSlot) &x
Hadn't thought of that. Looks like it works though.
> HideExpr
>
> { a }
> fn { a }()
> IgnorePattern
>
> _
> __1
> NounExpr
>
> a
> (&a).getValue()
> SeqExpr
>
> a; b
> __Mseq(a, b)
Yup.
> LiteralExpr
>
> 1.0
> __MlitInt."1.0"()
>
> "abc"
> __MlitString.abc()
>
> 'a'
> __MlitChar.a()
While I agree that these work, they are just too weird for my taste. I
would include the literals in Minimal-E, even though this isn't in
some sense minimal.
> CallExpr is in Minimal-E.
> DefineExpr, EMatcher, EMethod, EScript are in Minimal-E.
> ListPattern is in Minimal-E.
> MetaContextExpr, MetaStateExpr are in Minimal-E if they are in Kernel-E.
> ObjectExpr is in Minimal-E.
> SlotExpr, SlotPattern are in Minimal-E.
> ViaPattern is in Minimal-E.
Yes. After adding LiteralExpr back in, this looks like a good mininal set.
--
Text by me above is hereby placed in the public domain
Cheers,
--MarkM
-------------- next part --------------
A non-text attachment was scrubbed...
Name: __try.emaker
Type: e/unknown
Size: 1680 bytes
Desc: not available
Url : http://www.eros-os.org/pipermail/e-lang/attachments/20060705/c3ee10ed/attachment-0001.bin
More information about the e-lang
mailing list