Re: ellipsis & dot in `syntax-case` pattern
Ryan Culpepper <[email protected]>
| Newsgroups | gmane.comp.lang.racket.user,gmane.lisp.scheme.plt |
|---|---|
| Message-ID | <[email protected]> |
The short answer is that syntax-parse uses backtracking but syntax-case does something simpler. Here's how (I think) syntax-case matching works in Racket, in three stages of increasing complexity. Version 1: An ellipsis pattern must have the form (P ...). That is, the pattern after the ellipsis must be the empty list pattern. This is implemented by first trying to match the current term against (P . rest). If that succeeds, then recur on matching the rest term with the same ellipsis pattern. If that fails, then succeed if the current term is empty, otherwise fail. Version 2: An ellipsis pattern must have the form (P ... . T), where all terms matching T are improper lists with the same improper length (ie, the number of pairs before a non-pair when traversing cdrs). In particular, ellipsis patterns and pattern variables do not have predictable improper lengths. For example: (x ...) okay; tail length is 0 (x ... y "z") okay; tail length is 2 (x ... y z . 7) okay; tail length is 2 (x ... y ...) not okay (x ... y z . w) not okay The implementation is similar to version 1, except if the improper length of the *term* is equal to the improper length of the *pattern*, skip directly to trying to match the tail pattern. Version 3: An ellipsis pattern has the form (P ... . T), with no restrictions on T. IIUC, Racket acts like version 2 *if* the tail pattern has a fixed improper length; otherwise it does naive greedy matching: try (P . rest) first and the tail pattern if that fails. Ryan On 05/31/2018 05:12 AM, Matthew Butterick wrote: > According to the syntax-pattern grammar in the docs for `syntax-case` > [1] it should be possible to use an ellipsis and a dot in the same > syntax pattern. Yet this pattern fails to match the input. Why? > > #lang racket > (syntax-case #'(a "x" b) () > [(left ... "x" . right) #t] > [else #f]) ; #f > > (I know that `syntax-parse` will handle it correctly, but I'm still > curious what I'm missing about the behavior of `syntax-case`.) > > #lang racket > (require syntax/parse) > (syntax-parse #'(a "x" b) > [(left ... "x" . right) #t] > [else #f]) ; #t > > > [1] > https://docs.racket-lang.org/reference/stx-patterns.html?q=syntax-case#%28form._%28%28lib._racket%2Fprivate%2Fstxcase-scheme..rkt%29._syntax-case%29%29 > <https://docs.racket-lang.org/reference/stx-patterns.html?q=syntax-case#(form._((lib._racket/private/stxcase-scheme..rkt)._syntax-case))> > > -- > You received this message because you are subscribed to the Google > Groups "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send > an email to racket-users+unsubscribe-/[email protected] > <mailto:racket-users+unsubscribe-/[email protected]>. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/[email protected] For more options, visit https://groups.google.com/d/optout.