
TXR Lisp – an innovative, original dialect from the Lisp language family - pmoriarty
http://nongnu.org/txr/txr-lisp.html
======
kazinator
Help TXR!

A pattern matching implementation is badly needed for Lisp programming,
holding up work that benefits from it, like compiler work.

In terms of programmer interface, there are two "schools" for writing pattern
matchers: "match by printed notation" and "match by code". Succinctly: match
by code means (list a b) matches (1 2), binding (a 1) (b 2). Match by printed
notation means that you have something like (@a @b) instead which looks like
(1 2) but with explicitly denoted variables. Some "match by code" systems make
some use of backquote for this: `(,a ,b) matches (1 2). I think Fare's matcher
has something like this, for which it carried its own backquote
implementation.

I'm not attracted to "match by code". It doesn't scale to nested objects. Code
for constructing complicated, nested objects looks ugly. That's why Lisp got
backquote fifty years ago already. There can be many code variants that
produce the same thing. The user will be annoyed if (cons a b) is a valid
pattern, but (list* a b) isn't supported as an equivalent. How far do you take
it? Should (mapcar 'succ a) be a valid pattern which binds a to (0 1 2) for
the input (1 2 3)? I do have to acknowledge that simple cases of "match by
code" are readable.

TXR Lisp has support in its syntax for the future implementation of "match by
notation". The syntax _@ident_ produces the form (sys:var _ident_ ). _ident_
can be a symbol, or integer token. The former case is called "meta-varialble";
the latter "meta-number". The syntax _@expr_ produces (sys:expr _expr_ ),
where _expr_ can be a (...) or [...] compound (the latter being sugar for
(dwim ...). These notations can be coupled to a pattern matching system. For
instance, if we have a point structure with x y members, we could have a
pattern like #S(point x @column y @row). This is valid read syntax now:

    
    
      1> (defstruct point () x y)
      #<struct-type point>
      2> #S(point x @col y @row)
      #S(point x @col y @row)
      3> *2.x
      @col
      4> (car *2.x)
      sys:var
      5> (cadr *2.x)
      col
    

So we can imagine

    
    
      (match-case some-obj
         (#S(point x @col y @row) ... col and row are bound ...))
    

kind of thing.

