<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>