One thing I would like to see in Arc is a good and flexible way of approaching pattern patching. This is a small test for implementing or give an idea about how pattern matching could work in Arc. I personally would like something simple either to use as to implement. So I came up with the following: (def eqlst (lst1 lst2)
(if (and (no lst1) (no lst2))
t
(and (atom (car lst1)) (atom (car lst2)))
(if (is (len lst1) (len lst2))
(eqv (cdr lst1) (cdr lst2))
nil)
(and (isa (car lst1) 'cons) (isa (car lst2) 'cons))
(eqv (cdr lst1) (cdr lst2))
nil))
(set defp (annotate 'mac
(fn (name parms . body)
`(safeset ,name (fn ,parms
(let (match p) (list (pair ',body) ,@parms)
(let found (find [eqlst (car _) ,@parms] match)
(eval `(let ,(car found) ',p ,(cadr found))))))))))
The function would work like: (defp sum^mul (arg)
((z y) x) (+ (* z y) x)
(z y) (+ z y)
(z) (* z z))
Which gives the different pattern variations for sum^mul: (sum^mul '((126 9) 90)) => 1224
(sum^mul '(7 134)) => 141
(sum^mul '(13)) => 169
Notice how it returns nil in case none pattern is properly matched , which I think it is a good way of handling such a situation so we could get at the same time a nice pattern-finder function: (find [sum^mul _] '((13 (89)) ((34)) (45 7)))
Though I don't claim this is the best approach for implementing it ; I do think it is a very nice semantic for such an operation , and it is what this code snippet mainly try to show here.Comments? |