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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.