[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