<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>I'm not really sure why this works either, but try this:</div><div><br></div><div><div><font class="Apple-style-span" face="'Courier New'">(define-syntax (:match stx)</font></div><div><font class="Apple-style-span" face="'Courier New'"> (syntax-case stx ()</font></div><div><font class="Apple-style-span" face="'Courier New'">   [(:match val-expr [pat . more] ...)</font></div><div><font class="Apple-style-span" face="'Courier New'">    (with-syntax ([(new-pat ...) (for/list ([pat-stx (in-list (syntax->list #'(pat ...)))])</font></div><div><font class="Apple-style-span" face="'Courier New'">                                   (datum->syntax pat-stx `(:pat ,(syntax->datum pat-stx))))])</font></div><div><font class="Apple-style-span" face="'Courier New'">    #'(match val-expr [new-pat . more] ...))]))</font></div></div><div><font class="Apple-style-span" face="'Courier New'"><br></font></div><div><div><font class="Apple-style-span" face="'Courier New'">(check-equal? (:match '(42 x) [(list n:num s:sym) (list n s)])</font></div><div><font class="Apple-style-span" face="'Courier New'">              (match '(42 x) [(:pat (list n:num s:sym)) (list n s)]))</font></div></div><br><div><div>On Dec 29, 2013, at 8:54 AM, Jens Axel Søgaard wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Hi Alexander,<br><br>I extended your example to allow other patterns than symbols inside :pat.<br><br><blockquote type="cite"> (match '(42 x)  [(:pat (list n:num s:sym))   (list n s)])<br></blockquote>    (list 42 x)<br><br>This works fine. I now want to "hide" the :pat, that is I want to write:<br><br>    (:match '(42 x)  [(list n:num s:sym)  (list n s)])<br><br>Since the syntax of match is: (match val-expr clause ...) and each clause<br>has the form  [pat . more]  we can rewrite pat to [(:pat pat) . more].<br><br>So I tried this:<br><br>  (define-syntax (:match stx)<br>    (syntax-case stx ()<br>      [(_ val-expr [pat . more] ...)<br>       #'(match val-expr [(:pat pat) . more] ...)]))<br><br>This doesn't work however. I am tempted to consider this a bug in match,<br>but I am not sure.<br><br>#lang racket<br>(require (for-syntax (only-in lang/htdp-intermediate-lambda string-contains?)<br>                     racket/string<br>                     racket/match)<br>         rackunit)<br><br>(begin-for-syntax<br>  (define (type-str->stx-type-pred type-str)<br>    (match type-str<br>      ["num" #'number?]<br>      ["str" #'string?]<br>      ["sym" #'symbol?]<br>      ["lst" #'list?]<br>      [_ #f]))<br><br>  (define (split str) (string-split str ":"))<br><br>  (define (parse-pat-str pat-str stx)<br>    (match (split pat-str)<br>      [(list pat-name-str type-str)<br>       (with-syntax ([type-pred (type-str->stx-type-pred type-str)]<br>                     [pat-name (datum->syntax stx (string->symbol<br>pat-name-str))])<br>         #'(? type-pred pat-name))]))<br><br>  (define (id:type? str)<br>    (and (string-contains? ":" str)<br>         (type-str->stx-type-pred (cadr (split str))))))<br><br>(define-match-expander :pat<br>  (lambda (stx)<br>    (define (rewrite pat)<br>      (let* ([pat-sym (syntax->datum pat)]<br>             [pat-str (symbol->string pat-sym)])<br>        (if (id:type? pat-str)<br>            (parse-pat-str pat-str stx)<br>            pat)))<br>    (syntax-case stx ()<br>      [(_ pat) (identifier? #'pat) (rewrite #'pat)]<br>      [(_ (pat ...))<br>       (with-syntax ([(p ...) (map rewrite (syntax->list #'(pat ...)))])<br>         (syntax/loc stx (p ...)))]<br>      [(_ pat) #'pat])))<br><br>(define-syntax (:match stx)<br>  (syntax-case stx ()<br>    [(_ val-expr [pat . more] ...)<br>     #'(match val-expr [(:pat pat) . more] ...)]))<br><br><br>(check-equal? (match 1 [(:pat n:num) n]) 1)<br>(check-equal? (match 'x [(:pat n:num) n] [_ 2]) 2)<br><br>(check-equal? (match "string" [(:pat s:str) s]) "string")<br>(check-equal? (match 'x [(:pat s:str) s] [_ 2]) 2)<br><br>(check-equal? (match (list 1 2 3) [(:pat l:lst) l]) (list 1 2 3))<br>(check-equal? (match 'x [(:pat l:lst) l] [_ 2]) 2)<br><br>(check-equal? (match 'x [(:pat l) l]) 'x)<br><br>(check-equal? (match '(2 x "foo" (3 4)) [(:pat (list n s f l)) (list n<br>s f l)]) '(2 x "foo" (3 4)))<br>(check-equal? (match '(42 x) [(:pat (list n:num s:sym)) (list n s)]) '(42 x))<br><br><br>(match '(42 x) [(:pat (list n:num s:sym)) (list n s)])<br>; (:match '(42 x) [(list n:num s:sym) (list n s)])<br><br><br><br>2013/12/28 Alexander D.Knauth <<a href="mailto:alexander@knauth.org">alexander@knauth.org</a>>:<br><blockquote type="cite">I just wrote a match-expander that does something like that:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">(check-equal? (match 1 [(my-pat n:num) n]) 1)<br></blockquote><blockquote type="cite">(check-equal? (match 'x [(my-pat n:num) n] [_ 2]) 2)<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">like this:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">#lang racket<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">(require rackunit)<br></blockquote><blockquote type="cite">(require (for-syntax<br></blockquote><blockquote type="cite">          (only-in lang/htdp-intermediate-lambda<br></blockquote><blockquote type="cite">                   string-contains?)<br></blockquote><blockquote type="cite">          racket/string<br></blockquote><blockquote type="cite">          racket/match))<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">(define-match-expander my-pat<br></blockquote><blockquote type="cite">  (lambda (stx)<br></blockquote><blockquote type="cite">    (syntax-case stx ()<br></blockquote><blockquote type="cite">      [(my-pat pat)<br></blockquote><blockquote type="cite">       (let* ([pat-sym (syntax->datum #'pat)]<br></blockquote><blockquote type="cite">              [pat-str (symbol->string pat-sym)])<br></blockquote><blockquote type="cite">         (cond [(not (string-contains? ":" pat-str))<br></blockquote><blockquote type="cite">                #'pat]<br></blockquote><blockquote type="cite">               [else<br></blockquote><blockquote type="cite">                (parse-pat-str pat-str stx)]))])))<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">(define-for-syntax (parse-pat-str pat-str stx)<br></blockquote><blockquote type="cite">  (let ([split-pat (string-split pat-str ":")])<br></blockquote><blockquote type="cite">    (match split-pat<br></blockquote><blockquote type="cite">      [(list pat-name-str type-str)<br></blockquote><blockquote type="cite">       (with-syntax ([type-pred (type-str->stx-type-pred type-str)]<br></blockquote><blockquote type="cite">                     [pat-name (datum->syntax stx (string->symbol<br></blockquote><blockquote type="cite">pat-name-str))])<br></blockquote><blockquote type="cite">         #'(? type-pred pat-name))])))<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">(define-for-syntax (type-str->stx-type-pred type-str)<br></blockquote><blockquote type="cite">  (match type-str<br></blockquote><blockquote type="cite">    ["num" #'number?]<br></blockquote><blockquote type="cite">    ["str" #'string?]<br></blockquote><blockquote type="cite">    ["lst" #'list?]))<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">(check-equal? (match 1 [(my-pat n:num) n]) 1)<br></blockquote><blockquote type="cite">(check-equal? (match 'x [(my-pat n:num) n] [_ 2]) 2)<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">(check-equal? (match "string" [(my-pat s:str) s]) "string")<br></blockquote><blockquote type="cite">(check-equal? (match 'x [(my-pat s:str) s] [_ 2]) 2)<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">(check-equal? (match (list 1 2 3) [(my-pat l:lst) l]) (list 1 2 3))<br></blockquote><blockquote type="cite">(check-equal? (match 'x [(my-pat l:lst) l] [_ 2]) 2)<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">On Dec 26, 2013, at 2:45 PM, Jens Axel Søgaard wrote:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">The match pattern (? number? n) matches  number and<br></blockquote><blockquote type="cite">binds it to n.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">(match 1 [(? number? n) n])<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">  1<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">I'd like to write  (match 1 [n:num n]) instead.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Since there is no define-identifier-match-expander I have<br></blockquote><blockquote type="cite">tried to make (match 1 [(n:num) n]) work. I need a hint.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Here is a non-working attempt:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">(define-match-expander n:num<br></blockquote><blockquote type="cite"> (λ(stx)<br></blockquote><blockquote type="cite">   (syntax-case stx ()<br></blockquote><blockquote type="cite">     [(id)<br></blockquote><blockquote type="cite">      (with-syntax ([n (syntax/loc #'id n)])<br></blockquote><blockquote type="cite">        #'(? number? n))])))<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">(check-equal? (match 1 [(n:num) n]) 1)<br></blockquote><blockquote type="cite">(check-equal? (match 'x [(n:num) n] [_ 2]) 2)<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">/Jens Axel<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">--<br></blockquote><blockquote type="cite">Jens Axel Søgaard<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">____________________<br></blockquote><blockquote type="cite"> Racket Users list:<br></blockquote><blockquote type="cite"> <a href="http://lists.racket-lang.org/users">http://lists.racket-lang.org/users</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><br><br><br>-- <br>--<br>Jens Axel Søgaard<br></div></blockquote></div><br></body></html>