nhap96
nhap96

Reputation: 21

How to match constructed pattern in Racket?

I know we can pattern match using quasiquote patterns in Racket. For example:

> (match '(3) [`(,l) l])
3

However, I'm not sure if it's possible to achieve the same result with pre-existing patterns like

> (define pattern '`(,l))
> pattern
'`(,l)

How do I inject such pattern into the match clause?

Upvotes: 2

Views: 364

Answers (2)

Greg Hendershott
Greg Hendershott

Reputation: 16260

Although I’m not certain exactly what you want to accomplish, I want to point out that you can define match expanders. Keep in mind that, like match, these exist at compile- not run-time.

Upvotes: 0

Sylwester
Sylwester

Reputation: 48745

match is a macro. It uses its arguments, thus the patterns, from code before runtime. If you check the macro stepper (match '(3) [`(,l) l]) becomes this:

(let ([temp1 '(3)])
  (define (fail2) 
    (match:error temp1 (syntax-srclocs (quote-syntax srcloc)) 'match))
  (cond
   [(pair? temp1)
    (let ([unsafe-car4 (unsafe-car temp1)] [unsafe-cdr5 (unsafe-cdr temp1)])
      (cond
       [(null? unsafe-cdr5)
        (syntax-parameterize
         ([fail (make-rename-transformer (quote-syntax fail2))])
         (let ([l unsafe-car4]) (let () l)))]
       [else (fail2)]))]
   [else (fail2)]))

If you were to use the variable pattern in place of `(,1) it will just think you have a pattern that matches the whole argument. As show by this expansion of (match '(3) [pattern l]):

(let ([temp1 '(3)])
  (define (fail2) 
    (match:error temp1 (syntax-srclocs (quote-syntax srcloc)) 'match))
  (syntax-parameterize ([fail (make-rename-transformer (quote-syntax fail2))])
    (let ([pattern temp1]) (let () l))))

Your variable pattern doesn't exist before long after this have happened and thus match cannot take dynamic patterns. You need to move your pattern logic into the macro expansion time if the reason is that you want to abstract on many patterns, but that still are computable without input.

If you need patterns to be from input you cannot use match in this way. Perhaps you need to make something that does something similar in runtime.

Since the example is very basic I do not know what you are trying to achieve. I'm thinking this may be a XY problem.

Upvotes: 2

Related Questions