[e-lang] Missing features in pattern failure

Kevin Reid kpreid at mac.com
Fri Feb 6 20:18:22 EST 2009


   accum [].asMap() for [k, v] in foo { _.with(k, v) }

This code does not do the right thing if one of the elements of foo is  
not a pair: it will skip it rather than failing. Currently this has to  
be rewritten using an explicit def:

   accum [].asMap() for temp ? (def [k, v] := temp; true) in foo  
{ _.with(f(k), f(v)) }

or

   accum [].asMap() for temp in foo { _.with(def [k, v] := temp; f(k),  
f(v)) }

but both of these are ugly.

What I would like for this is something like Haskell's "irrefutable  
patterns", which turn match failure in a subpattern into a program  
failure.

This comes to mind:

   accum [].asMap() for via (irrefutable) [k, v] in foo { _.with(f(k),  
f(v)) }

but with the current protocol for a via-function, it can't control  
what ejector is supplied to a subpattern.

This inability has another effect:
----------------------------------------------------------------------

Since nothing in in a Kernel-E pattern does or can substitute the  
ejector, once a match of some pattern against some value has failed,  
it is impossible to reconstruct which part of the value did not match.  
If the ejectors for subpatterns were nested (much as happens in the  
interaction between TextWriters and printed objects) then we could  
construct a chain of nested exceptions as we unwind in the pattern  
which documents where the failure was.

Example:

   def [==1, [==2, [==3, ==4]]] := [1, [2, [9, 4]]]

would generate the exception

   makeTupleFailure(1,
     makeTupleFailure(1,
       makeTupleFailure(0,
         makeSamePattFailure(9, 3)))

When each ListPattern executes its subpatterns, it provides an ejector  
which calls the outer ejector:

   to matchBind(specimen, ejector, env) {
     for index => subpattern in myPatterns {
       subpattern.matchBind(specimen, fn subfailure {
         ejector(makeTupleFailure(index, subfailure))
       }, env)
     }
   }

Similarly, ViaPattern would need to be changed such that the via- 
function can specify the ejector the subpattern gets, as well as the  
specimen.

(ListPattern and ViaPattern are the only non-atomic patterns remaining  
in Kernel-E.)


I think this might enable some interesting uses, but I don't have any  
concrete examples besides "nice error messages". They would be very  
nice error messages, though.

On the other hand, it's a lot of objects to be allocated. But a lot of  
uses of 'via' generate closures each time anyway; perhaps the answer  
is "just" work on optimizing them out (don't make reified nested  
ejectors if you can compile the patterns; don't make exceptions if  
nothing is looking).

-- 
Kevin Reid                            <http://homepage.mac.com/kpreid/>




More information about the e-lang mailing list