[e-lang] Killing the MatchBindExpr
Kevin Reid
kpreid at attglobal.net
Wed May 3 09:26:08 EDT 2006
On May 3, 2006, at 2:31, Mark S. Miller wrote:
> Dean observes that the MatchBindExpr is generally useful only when
> used as the
> conditional in a conditional flow of control context like an 'if'.
> When used
> in this context, it is also not problematic. The problems come from
> making the
> MatchBindExpr into a full fledged expression, merely in order to
> use it as the
> conditional in this context. By being a full fledged expression
> which returns
> a boolean, Kernel-E then has to cope with the consequences of
> control flow
> continuing past a match failure, into the code where the variables
> defined by
> the pattern are in scope, but where they haven't been bound by a
> successful
> pattern match.
>
> To reiterate a previous example:
>
> ? [1,2] =~ [x, y :char]
> # value: false
>
> ? y
> # value: <ref broken by problem: <ClassCastException: \
> # Integer doesn't coerce to a Character>>
>
> My previous email failed to point out the worst problem with the above
> behavior: The definition of 'y' is guarded by ':char'. Surely,
> then, within
> the resulting scope, we can count on 'y' having a character as its
> value? The
> above counter-example shows that E is currently not faithful to
> this intuition.
Possible fix: Instead of breaking the /values/, break the /slots/
(Ref.isBroken(&y) => true). Then, attempting to access y would throw
an exception. This would work even for user SlotPatterns since a
broken reference is (mostly) unambiguously not a useful value.
> Dean suggests that, instead, Kernel-E should bundle pattern match
> with if-like
> conditional control flow, combining them into one construct. Here
> are two
> possibilities, the if-match and the extended-switch, either of
> which could
> replace the current MatchBindExpr in Kernel-E
>
> 1) if-match:
>
> e ::= if (e1) =~ p1 {e2} else {e3}
>
> The if-match would be in addition to the existing 'if' production.
> As with the
> existing 'if', e2 is evaluated in the scope resulting from the 'if'
> head, here
> e1 and p1; but e3 is not. In E, we'd allow the normal 'else if'
> chaining to
> mix these two forms of 'if' without worry. Such chaining would
> expand into
> Kernel-E nesting just like it does now.
This trivially expands to the previously discussed left-to-right-
kernel-define, which I think is an appropriate and widely useful
primitive:
escape fail__1 {
define (e1, fail__1) =~ p1
e2
} catch _ {
e3
}
Therefore, since "if-match" is unexpressive by discarding the
exception, and can't replace all trinary-defines even if that were
fixed, I think it should not be part of Kernel-E. It might well be a
worthwhile nonkernel construct, however, even replacing the nonkernel
match-bind we discussed.
If a review of existing code shows that all uses of match-bind can be
rewritten into if-match or trinary-define, then I would be in favor
of replacing match-bind with nonkernel if-match.
(Incidentally, after trying to use the ltr-define, I think the
parentheses are confusing; the ejector is more related to the pattern
than the specimen. I don't know how to fix this, yet.)
--
Kevin Reid <http://homepage.mac.com/kpreid/>
More information about the e-lang
mailing list