Announcing E 0.8.4: The Birthday Release

Mark S. Miller markm@caplet.com
Tue, 01 Jun 1999 00:54:31 -0700


At 04:10 PM 5/27/99 , Dan Bornstein wrote:
>* visitMatchBindExpr: I'm not sure exactly how to expand this (since I'm
>not totally sure of the semantics and casual inspection of the E website
>revealed no example usages for me to go on), but I think you may be able to
>introduce a primitive "performMatch" function and expand this:
>
>  <specimen> =~ <patt>
>
>to something like this:
>
>  { 
>    define [__result, <specimen-vars>] := 
>      performMatch(<specimen-spec>, <patt>)
>      __result 
>  }

[-] Would require other invention.
This would require a transformation from a pattern to an expression 
representing the pattern.  An interesting idea, but I don't immediately see 
how to do this.

I haven't yet adequately explained the semantics of patterns, and I 
desperately need to.  Let's revisit this one when I do.  (But see below for 
a start.)

Btw, note that unless you remove the surrounding curlies from your expansion 
the bindings resulting from the match would not be available following the 
match, which is not the intended meaning.


>* visitObjectExpr, visitPlumbingExpr: I find the definition of these nodes
>to be disturbing in that they combine object definition with variable
>binding. You already have a "define" primitive which should cover the
>variable binding side of things. Maybe you still need primitives to cover
>the object definition part of these (maybe not--again, I apologize for not
>being sure enough of the sementics), but at least you could consolidate
>the "define" part.

[-] I have lost my faith in anonymous closures.
I have made the name of the variable being defined part of the object 
expression, so that this object expression will know this name.  The minor 
but pleasant user interface payoff: If the object does not provide its own 
printOn method, a Miranda method will be provided for it that will print 
using that name:

	? define bletch {
	>     //...
	> }
	# value: <bletch>

	? define zorch := bletch
	# value: <bletch>

	? zorch
	# value: <bletch>

If the object expression doesn't know its name, there's no principled way to 
do this.

The motivating payoff (as documented badly and too briefly by 
http://www.erights.org/elang/elangmanual.pdf Chapter 4, page 39) is upgrade 
preserving old object state and identity, while changing the behavior to 
correspond to a new version of the code.  No system that I know of 
(Smalltalk included) attempts to upgrade anonymous closures, but Smalltalk's 
rapid prototyping support does depend on upgrade of instances of named 
classes.  E doesn't have this distinction, but instead just uniformly has 
named object expressions.  (Anyone know Self's stance on this?)

What I imagine is that expressions are evaluated in an expression context, 
and this context, besides providing the outer variable scope, also provides 
a "behavior name space" in which object expressions register their VTable 
under their fully-qualified object expression name.  The fully qualified 
object expression name is the dot separated path of enclosing object 
expression names, terminating in the name of the object expression in question.

(If any name of this path is instead "_" then, for purposes of upgrade, this 
is an anonymous object expression whose instances cannot be upgraded.  These 
would not register in the behavior table.)

If, on registering, the object expression finds a previous VTable already 
registered by this name, it would replace this VTable in the table, but it 
would also side-effect this VTable so that, on next execution of any of its 
instances, that instance would get upgraded to use the new VTable instead.  
The extra indirection gives the new behavior the opportunity to convert the 
old data to a format appropriate to the new behavior.

Unless a pressing need comes up, I'm not planning to actually implement this 
upgrade mechanism this millennium, but bitter experience has shown that 
upgrade, like security, is something to architect for from the beginning.


>* visitCatchExpr: With a "tryCatch" primitive function, this:
>
>  try { <attempt> } catch <patt> { <catcher> }
>
>could expand to (approximately):
>
>  tryCatch (object { to { <attempt> } }, 
>            object { to(__except) { if (<patt> ? __except) { <catcher> } } })

[-] Fails previous criterion.


>* visitFinallyExpr: With a "tryFinally" primitive function, this:
>
>  try { <attempt> } finally { <unwinder> }
>
>could expand to (approximately):
>
>  tryFinally (object { to { <attempt> } },
>              object { to { <unwinder> } })

[-] Fails previous criterion.


>* visitPatternSuchThat: I couldn't find a clear definition of this
>node. The text on the javadoc page alludes to a pattern, a specimen,
>and a test, but the syntax is just:
>
>  <patt> ? <test>
>
>with no specimen to be seen anywhere. My guess is that this could expand in
>terms of the same "performMatch" I posited for expanding "=~" but again I'm
>not familiar enough with the semantics to be too sure of this analysis.

[#] The specimen is provided to the pattern by pattern-evaluation.
The basic E expression-evaluation function could be describes as

	eval(expr, scope) yields [expr, newScope]

For pattern-evaluation, we have instead

	test(pattern, specimen, scope) yields [boolean, newScope]

For example, in 

	<expr> =~ <patt>

or

	define <patt> := <expr>

the specimen is the result of evaluating <expr>.  In

	define bletch {
	    to foo(<patt1>, <patt2>) {

the specimens are the corresponding message arguments.

With all that said, I don't know whether there's a good expansion of the 
such-that pattern into more primitive constructs.  It'd be good it you gave 
it another shot.


>Sorry I don't have too many cycles to devote to thinking about E, but I
>hope this helps.

[+] Indeed it does!
Even where I disagree, it gets me to explain my rationale, which is exactly 
what I need to be doing right now.


	Cheers,
	--MarkM