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