Search code examples
racketplt-redex

Ellipsis over unquote in redex term


I'm trying to define a Redex metafunction that converts a list of pairs into a list of single numbers, as follows:

#lang racket
(require redex)

(define-language L
   (e n ((n n) ...) (n ...))
   (n number))

(define-metafunction L
   ((add-up n) n)
   ((add-up ((e_1 e_2) ...)) (,(+ (term e_1) (term e_2)) ...)))

However, the last definition for add-up isn't accepted - Redex complains about e_1 and e_2 requiring an ellipsis, despite them already being below one ellipsis. Is there a way to apply a Racket unquote to each member of an ellipsis in Redex?


Solution

  • The problem here is that you have the pattern variables e_1 and e_2 separated from the ellipses ... by an unquote (,). The Redex pattern matcher is not clever enough to look through unquotes because you can put arbitrary Racket there.

    What you can do however, is use Racket constructs (in this case specifically map) to add up your numbers. The expression will look like this:

    ,(map + (term (e_1 ...)) (term (e_2 ...)))
    

    Or putting it all together:

    #lang racket
    (require redex)
    
    (define-language L
       (e n ((n n) ...) (n ...))
       (n number))
    
    (define-metafunction L
       ((add-up n) n)
       ((add-up ((e_1 e_2) ...)) ,(map + (term (e_1 ...)) (term (e_2 ...)))))