[e-lang] Atomic expansion of MatchBindExpr to trinary-define

Mark S. Miller markm at cs.jhu.edu
Mon May 1 01:46:49 EDT 2006


My summary of Kernel-E productions included the following three:

e ::= def p := e                                          # DefineExpr
    |  def p := (e1, e2)                                   # DefineExpr
    |  e =~ p                                              # MatchBindExpr

The middle production is the trinary-define expression. 'p' and 'e1' serve the 
same roles as the 'p' and 'e', respectively, in the normal define expression. 
'e2' is evaluated to the ejector used when matching 'p' against 'e1's value. 
The first production, 'def p := e', could be defined by expansion to
'def p := (e, null)'. Because both define expressions executes right-to-left, 
it imposes the restriction that neither side can use any variables defined by 
the other. This restriction makes their effects on scoping commutative, so 
that a Kernel-E implementation can evaluate the right side before the left 
side without needing any further mechanism to support E's left-to-right scoping.

Trinary define would seem to subsume as well the MatchBindExpr, except that 
the MatchBindExpr follows E's normal left-to-right scoping rule, so that 'p' 
can use variables defined by 'e'.

Dean points out that if we give the trinary-define a syntax with a 
left-to-right order that matches its execution order, (e1, e2, p), then we can 
allow it to follow E's normal left-to-right scoping rules without restriction. 
At that point, we should be able to express MatchBindExpr as an expansion to 
trinary-define.

We don't currently have a concrete syntax for trinary-define which anyone 
likes. For purposes of discussion, we're using the syntax

     e ::= keyword (e1, e2) =~ p

Perhaps, with an appropriate choice of keyword, this syntax will be just fine. 
Suggestions?

Given this form of trinary-define, Kevin proposes that, for example,

     left =~ [rA, &rB, [rC]]

should expand to

     def specimen__1 := left
     keyword(escape ej {
                 keyword(specimen__1, ej) =~ [rA, &rB, [rC]]
                 [true, rA, &rB, rC]
             } catch ex__1 {
                 def b__1 := Ref.broken(ex__1)
                 [false, b__1, b__1, b__1]
             },
             null) =~ [result__1, rA, &rB, rC]
     result__1

In this expansion, if 'rA' succeeds but '[rC]' fails, the inner 'rA' stays 
bound and the outer 'rA' is bound to a broken reference. They are explicitly 
different variables, as the semantics of atomic binding demands.

-- 
Text by me above is hereby placed in the public domain

     Cheers,
     --MarkM



More information about the e-lang mailing list