[racket-dev] [plt-scheme] Bug or misuse? match-expander ids not properly working (patch)

From: Carl Eastlund (cce at ccs.neu.edu)
Date: Fri May 4 14:28:57 EDT 2012

If we add some kind of id expanders for match patterns, we need to add a
way for pattern variables to shadow these names if the author really wants
to.  Otherwise, every id expander defined eats up more namespace that match
variables cannot bind.

We already have this issue with _ and ..., but at least that's a known set
of constant size.

Carl Eastlund

On Fri, May 4, 2012 at 2:16 PM, Eli Barzilay <eli at barzilay.org> wrote:

> This is an *ancient* patch suggestion that I dug up in my quest for
> smaller inbox...  (It's really old, so won't work as is.)
>
> It makes it possible to define identifier syntaxes as match expanders,
> and that would probably make it possible to also address the
> relatively common complaint about not having a `null' match pattern
> that does the obvious thing.  Last time we talked about this (= me &
> Sam) I think that there was some point about identifiers being
> unambiguously used as patterns -- but I don't see a problem with the
> following approach of specifying specific names as patterns.  If the
> builtin identifier patterns are kept to a minimum (for example, only
> `null', `true' and `false'), then I don't think that this will be
> confusing in any way.
>
>
> On November 24th 2009, Madoka Machitani wrote:
> > Hi!
> >
> > I've encountered a problem while implementing red-black trees:
> >
> > (define-struct tree
> >   (color key value left right))
> >
> > (define empty (make-tree 'black #f #f #f #f))
> > (define (empty? t) (eq? t empty))
> >
> >
> > To ease access with the pattern match syntax, I wrote match expanders
> > for trees as follows:
> >
> > (define-match-expander T
> >   (lambda (stx)
> >     (syntax-case stx ()
> >       ((T c l (k v) r)
> >        (syntax/loc stx
> >          (struct tree (c k v l r))))))
> >   (lambda (stx)
> >     (syntax-case stx ()
> >       ((T c l (k v) r)
> >        (syntax/loc stx
> >          (make-tree c k v l r))))))
> >
> > (define-match-expander R
> >   (lambda (stx)
> >     (syntax-case stx ()
> >       (R (syntax 'red))))
> >   (lambda (stx)
> >     (syntax-case stx ()
> >       (R (syntax 'red)))))
> >
> > (define-match-expander B
> >   (lambda (stx)
> >     (syntax-case stx ()
> >       (B (syntax 'black))))
> >   (lambda (stx)
> >     (syntax-case stx ()
> >       (B (syntax 'black)))))
> >
> > (define-match-expander E
> >   (lambda (stx)
> >     (syntax-case stx ()
> >       (E (syntax/loc stx (? empty?)))))
> >   (lambda (stx)
> >     (syntax-case stx ()
> >       (E (syntax/loc stx empty)))))
> >
> >
> > which should enable one to construct and match trees a la Haskell:
> >
> > (match (T B E ('a 1) E)
> >   ((T B E (k v) E)
> >    "This is a black tree with both subtrees empty."))
> >
> >
> > However, this doesn't work as I expected.  I.e., "B" and "E" in the
> > pattern clause above are treated as plain variables, thus matching
> > anything.  Seemingly match expander ids in pattern match clauses take
> > effect only when used in "application" form.
> >
> > So I wrote a patch.
> >
> > The first portion is irrelevant to this particular issue, but fixes
> > a bug which inecessarily converts unnamed let syntax to a named one.
> >
> > The second part is required for the third one to work when only
> > expander ids are used in match-let etc bindings.
> >
> > I hope it's accepted.
> >
> > regards,
> >
> > diff -ur orig/define-forms.ss ./define-forms.ss
> > --- orig/define-forms.ss      2009-09-17 12:09:40.000000000 +0900
> > +++ ./define-forms.ss 2009-11-25 13:23:40.000000000 +0900
> > @@ -72,7 +72,7 @@
> >           ;; optimize the all-variable case
> >           [(_ ([pat exp]...) body ...)
> >            (andmap pattern-var? (syntax->list #'(pat ...)))
> > -          (syntax/loc stx (let name ([pat exp] ...) body ...))]
> > +          (syntax/loc stx (let ([pat exp] ...) body ...))]
> >           [(_ name ([pat exp]...) body ...)
> >            (and (identifier? (syntax name))
> >                 (andmap pattern-var? (syntax->list #'(pat ...))))
> > diff -ur orig/parse-helper.ss ./parse-helper.ss
> > --- orig/parse-helper.ss      2009-09-17 12:09:40.000000000 +0900
> > +++ ./parse-helper.ss 2009-11-25 13:44:34.000000000 +0900
> > @@ -141,10 +141,17 @@
> >  (define (match:syntax-err stx msg)
> >    (raise-syntax-error #f msg stx))
> >
> > +;; match-var? : syntax -> bool
> > +;; is p an identifier representing a pattern transformer?
> > +(define (match-var? p)
> > +  (match-expander?
> > +   (syntax-local-value ((syntax-local-certifier) p)
> > +                    (lambda () #f))))
> > +
> >  ;; pattern-var? : syntax -> bool
> >  ;; is p an identifier representing a pattern variable?
> >  (define (pattern-var? p)
> > -  (and (identifier? p) (not (ddk? p))))
> > +  (and (identifier? p) (not (ddk? p)) (not (match-var? p))))
> >
> >  ;; ddk? : syntax -> number or boolean
> >  ;; if #f is returned, was not a ddk identifier
> > diff -ur orig/parse.ss ./parse.ss
> > --- orig/parse.ss     2009-09-17 12:09:40.000000000 +0900
> > +++ ./parse.ss        2009-11-25 01:44:44.000000000 +0900
> > @@ -32,6 +32,13 @@
> >       (match-expander-transform
> >        parse/cert cert #'expander stx match-expander-match-xform
> >        "This expander only works with the legacy match syntax")]
> > +    [expander
> > +     (and (identifier? #'expander)
> > +          (match-expander? (syntax-local-value (cert #'expander)
> > +                                               (lambda () #f))))
> > +     (match-expander-transform
> > +      parse/cert cert #'expander stx match-expander-match-xform
> > +      "This expander only works with the legacy match syntax")]
> >      [(var v)
> >       (identifier? #'v)
> >       (make-Var #'v)]
> > _________________________________________________
> >   For list-related administrative tasks:
> >   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> --
>          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                    http://barzilay.org/                   Maze is Life!
> _________________________
>  Racket Developers list:
>  http://lists.racket-lang.org/dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20120504/3e2f1bed/attachment-0001.html>

Posted on the dev mailing list.