An old topic revisited

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

An old topic revisited

Richard A. O'Keefe-2
Some time ago we had a thread about OR-patterns,
where amongst other things,
  pattern ::= ... | or_pattern
  or_pattern ::= pattern '|' pattern

A|B matches X if A matches X or B matches X,
A and B must bind the same variables.

The argument was made that it is painfully common
to have functions or cases with duplicate bodies
forced by matching different patterns.  As a
trivial example, take

f(ok | {info,_}, State) -> g(State);
f({warning,E} | {fatal,E}, State) -> crash(E, State).

At the time I pointed out that this could be done using
abstract patterns, quite easily.  (So why don't we have
abstract patterns yet hint hint.)

The same question came up recently in the Haskell
mailing list, for the same kind of reason.

It occurred to me to try the feature.
SML/NJ has OR-patterns.  So consider

fun f ((1,_)|(_,1)) ... ((n,_)|(_,n)) (0,0) = true
  | f       _       ...       _         _   = false
fun g () = f (1,1) ... (n,n) (1,1)

Now the smlnj compiler is normally pretty quick.
And I thought it might be quick on this.
What I really wanted was to measure how long it took
to run, for different values of n.
But I started with n=20, and so far, the compiler
has taken 24 minutes on a 3.2 GHz machine with no
end in sight.

In contrast, using view patterns in Haskell
(the Haskell equivalent of abstract patterns),

ok n (x,_) | x == n = True
ok n (_,x) | x == n = True
ok _ (_,_)          = False

f (ok 1 -> True) ... (ok n -> True) (0,0) = True
f       _                  _          _   = False

g () = f (1,1) ... (n,n) (1,1)

loads into ghci very fast, and g () runs faster.




_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions