[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