[e-lang] Is the SuchThatPattern always a bad idea?

Mark Miller markm at cs.jhu.edu
Mon Aug 8 08:19:05 EDT 2005


Darius Bacon wrote:
> Mark Miller <markm at cs.jhu.edu> wrote:
>>If '<p1>' is the pattern '<p2> :<e2>', then the meaning is, first evaluate 
>><e2> to a guard, coerce the specimen by this guard, and then match the 
>>coercion result against <p2>.
> 
> Doesn't this break left-to-right evaluation if <p2> happens to have
> embedded expressions?  I guess you could handle this by statically
> disallowing patterns where this would matter -- I think you've already
> made that sort of rule for other Kernel-E expansions.


Disallowing is the right answer. This is already the answer for the variable 
definition pattern this proposal generalizes from. The pattern 'x :x' obeys 
the current grammar of E but is rejected when trying to make the FinalPattern 
AST node.

     ? epatt`x :x`
     # problem: Failed: kernel definer cycle not allowed: x

In the more general case, the no-cycle rule should be that in '<p2> :<e2>', 
none of the variables defined and exposed by either (ast.outNames()) can be 
used freely by the other (ast.namesUsed()).

Unfortunately, the proposed new expansions combined with the no-cycle rule 
will cause some E patterns, which seem to make perfect sense by the 
left-to-right rule, to be rejected because their expansion to Kernel-E 
violates the no-cycle rule:

     ["x" => y, (y) => z]
=>  t1 ? (t1.optExtract("x") =~
             [y, t2 ? (t2.optExtract(y) =~
                         [z, t3 ? (t3.size() == 0)])])
->  [y, [z , _ :Empty] :Extract[y]] :Extract[x]

The pattern the user wrote makes perfect sense: Extract the value associated 
with the key "x", bind this value to y, and use it as a key to look up the 
value to bind to z. The current expansion, shown after the "=>", implements 
this correctly. The proposed new expansion will be rejected for reasons that 
are mostly inexplicable at the source level. However, this rejection fails 
safe: For any E program which is accepted, the reordering introduced by the 
expansion to Kernel-E cannot cause E's left-to-right scoping rule to be violated.

By contrast, the current quasiliteral expansion fails unsafe. As explained at 
<http://www.erights.org/data/irrelevance.html>:

     In the expansion of, for example, the quasi-pattern
     `-$i- at i-@j-$j-`, the relative order among the embedded dollar-hole
     expressions is preserved, and the relative order among the at-hole
     patterns is preserved, but all the extracted expressions occur in
     the expansion to the left of all the extracted patterns. As one
     would expect from the pre-expansion text, $i refers to the i
     already in scope, not that defined by @i. But $j also refers to
     the j already in scope, not the j defined by @j. This violates the
     left-to-right rule. E must instead statically reject the program,
     rather than allow a reader to be confused about the meaning of $j.

The static rejection specified above is still unimplemented, as it would 
require additional mechanism somewhere. The proposed new expansion applied to 
this example gives

->  [i, j] :MatchBind[
         simple__quasiParser.matchMaker("-${0}-@{0}-@{1}-${1}"),
         [i, j]]

which fails safe. It would be rejected by the no-cycle rule without any 
additional mechanisms.

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

     Cheers,
     --MarkM



More information about the e-lang mailing list