Search code examples
racket

Multiple ellipsis when defining syntax


I need to define a syntax for a fancy-sublist procedure that works like this

> (fancy-sublist 1 2 -> 3 4 5 <- 6 7)
(3 4 5)

I tried to implement it by defining a new syntax

(define-syntax fancy-sublist
  (syntax-rules (-> <-)
    ((_ x xs ... -> dis dis1 ... <- y ys ...) 
      (keep only the elements in the middle))))

But it seems I cannot put an ellipsis after another.

Is it possible to use define-syntax to do what I want?


Solution

  • Use the syntax/parse library instead of syntax-rules; it’s more capable in every way, and it produces considerably better error messages even when both can technically get the job done. I consider syntax-rules a legacy feature from Scheme; syntax-parse should really be the default choice in modern Racket. It copes with your example perfectly fine:

    #lang racket
    
    (require syntax/parse/define)
    
    (define-syntax (<- stx)
      (raise-syntax-error #f "cannot be used as an expression" stx))
    
    (define-syntax-parser fancy-sublist
      #:literals [<- ->]
      [(_ x xs ... -> dis dis1 ... <- y ys ...)
       #'(list dis dis1 ...)])
    
    > (fancy-sublist 1 2 -> 3 4 5 <- 6 7)
    '(3 4 5)