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&#39;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">&lt;<a href="mailto:eli@barzilay.org" target="_blank">eli@barzilay.org</a>&gt;</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&#39;s really old, so won&#39;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&#39; match pattern<br>
that does the obvious thing.  Last time we talked about this (= me &amp;<br>
Sam) I think that there was some point about identifiers being<br>
unambiguously used as patterns -- but I don&#39;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&#39;, `true&#39; and `false&#39;), then I don&#39;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>
&gt; Hi!<br>
&gt;<br>
&gt; I&#39;ve encountered a problem while implementing red-black trees:<br>
&gt;<br>
&gt; (define-struct tree<br>
&gt;   (color key value left right))<br>
&gt;<br>
&gt; (define empty (make-tree &#39;black #f #f #f #f))<br>
&gt; (define (empty? t) (eq? t empty))<br>
&gt;<br>
&gt;<br>
&gt; To ease access with the pattern match syntax, I wrote match expanders<br>
&gt; for trees as follows:<br>
&gt;<br>
&gt; (define-match-expander T<br>
&gt;   (lambda (stx)<br>
&gt;     (syntax-case stx ()<br>
&gt;       ((T c l (k v) r)<br>
&gt;        (syntax/loc stx<br>
&gt;          (struct tree (c k v l r))))))<br>
&gt;   (lambda (stx)<br>
&gt;     (syntax-case stx ()<br>
&gt;       ((T c l (k v) r)<br>
&gt;        (syntax/loc stx<br>
&gt;          (make-tree c k v l r))))))<br>
&gt;<br>
&gt; (define-match-expander R<br>
&gt;   (lambda (stx)<br>
&gt;     (syntax-case stx ()<br>
&gt;       (R (syntax &#39;red))))<br>
&gt;   (lambda (stx)<br>
&gt;     (syntax-case stx ()<br>
&gt;       (R (syntax &#39;red)))))<br>
&gt;<br>
&gt; (define-match-expander B<br>
&gt;   (lambda (stx)<br>
&gt;     (syntax-case stx ()<br>
&gt;       (B (syntax &#39;black))))<br>
&gt;   (lambda (stx)<br>
&gt;     (syntax-case stx ()<br>
&gt;       (B (syntax &#39;black)))))<br>
&gt;<br>
&gt; (define-match-expander E<br>
&gt;   (lambda (stx)<br>
&gt;     (syntax-case stx ()<br>
&gt;       (E (syntax/loc stx (? empty?)))))<br>
&gt;   (lambda (stx)<br>
&gt;     (syntax-case stx ()<br>
&gt;       (E (syntax/loc stx empty)))))<br>
&gt;<br>
&gt;<br>
&gt; which should enable one to construct and match trees a la Haskell:<br>
&gt;<br>
&gt; (match (T B E (&#39;a 1) E)<br>
&gt;   ((T B E (k v) E)<br>
&gt;    &quot;This is a black tree with both subtrees empty.&quot;))<br>
&gt;<br>
&gt;<br>
&gt; However, this doesn&#39;t work as I expected.  I.e., &quot;B&quot; and &quot;E&quot; in the<br>
&gt; pattern clause above are treated as plain variables, thus matching<br>
&gt; anything.  Seemingly match expander ids in pattern match clauses take<br>
&gt; effect only when used in &quot;application&quot; form.<br>
&gt;<br>
&gt; So I wrote a patch.<br>
&gt;<br>
&gt; The first portion is irrelevant to this particular issue, but fixes<br>
&gt; a bug which inecessarily converts unnamed let syntax to a named one.<br>
&gt;<br>
&gt; The second part is required for the third one to work when only<br>
&gt; expander ids are used in match-let etc bindings.<br>
&gt;<br>
&gt; I hope it&#39;s accepted.<br>
&gt;<br>
&gt; regards,<br>
&gt;<br>
&gt; diff -ur orig/define-forms.ss ./define-forms.ss<br>
&gt; --- orig/define-forms.ss      2009-09-17 12:09:40.000000000 +0900<br>
&gt; +++ ./define-forms.ss 2009-11-25 13:23:40.000000000 +0900<br>
&gt; @@ -72,7 +72,7 @@<br>
&gt;           ;; optimize the all-variable case<br>
&gt;           [(_ ([pat exp]...) body ...)<br>
&gt;            (andmap pattern-var? (syntax-&gt;list #&#39;(pat ...)))<br>
&gt; -          (syntax/loc stx (let name ([pat exp] ...) body ...))]<br>
&gt; +          (syntax/loc stx (let ([pat exp] ...) body ...))]<br>
&gt;           [(_ name ([pat exp]...) body ...)<br>
&gt;            (and (identifier? (syntax name))<br>
&gt;                 (andmap pattern-var? (syntax-&gt;list #&#39;(pat ...))))<br>
&gt; diff -ur orig/parse-helper.ss ./parse-helper.ss<br>
&gt; --- orig/parse-helper.ss      2009-09-17 12:09:40.000000000 +0900<br>
&gt; +++ ./parse-helper.ss 2009-11-25 13:44:34.000000000 +0900<br>
&gt; @@ -141,10 +141,17 @@<br>
&gt;  (define (match:syntax-err stx msg)<br>
&gt;    (raise-syntax-error #f msg stx))<br>
&gt;<br>
&gt; +;; match-var? : syntax -&gt; bool<br>
&gt; +;; is p an identifier representing a pattern transformer?<br>
&gt; +(define (match-var? p)<br>
&gt; +  (match-expander?<br>
&gt; +   (syntax-local-value ((syntax-local-certifier) p)<br>
&gt; +                    (lambda () #f))))<br>
&gt; +<br>
&gt;  ;; pattern-var? : syntax -&gt; bool<br>
&gt;  ;; is p an identifier representing a pattern variable?<br>
&gt;  (define (pattern-var? p)<br>
&gt; -  (and (identifier? p) (not (ddk? p))))<br>
&gt; +  (and (identifier? p) (not (ddk? p)) (not (match-var? p))))<br>
&gt;<br>
&gt;  ;; ddk? : syntax -&gt; number or boolean<br>
&gt;  ;; if #f is returned, was not a ddk identifier<br>
&gt; diff -ur orig/parse.ss ./parse.ss<br>
&gt; --- orig/parse.ss     2009-09-17 12:09:40.000000000 +0900<br>
&gt; +++ ./parse.ss        2009-11-25 01:44:44.000000000 +0900<br>
&gt; @@ -32,6 +32,13 @@<br>
&gt;       (match-expander-transform<br>
&gt;        parse/cert cert #&#39;expander stx match-expander-match-xform<br>
&gt;        &quot;This expander only works with the legacy match syntax&quot;)]<br>
&gt; +    [expander<br>
&gt; +     (and (identifier? #&#39;expander)<br>
&gt; +          (match-expander? (syntax-local-value (cert #&#39;expander)<br>
&gt; +                                               (lambda () #f))))<br>
&gt; +     (match-expander-transform<br>
&gt; +      parse/cert cert #&#39;expander stx match-expander-match-xform<br>
&gt; +      &quot;This expander only works with the legacy match syntax&quot;)]<br>
&gt;      [(var v)<br>
&gt;       (identifier? #&#39;v)<br>
&gt;       (make-Var #&#39;v)]<br>
&gt; _________________________________________________<br>
&gt;   For list-related administrative tasks:<br>
&gt;   <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>