pattern-matchingschemechicken-scheme

List to pattern conversion in matchable (Chicken scheme)


I have a list of patterns, how can I convert them to fit into the match function?

(use matchable)
(define prop '(and (#t #t) #t))
(define patt '(and (X Y) Z)) ;;here is the pattern example
(match prop [('and (X Y) Z) (list X Y Z)])) ;;(#t #t #t) this works
(match prop [patt (list X Y Z)])) ;;anything matches the pattern???

The last match doesn't work, all my variables are symbols, I'm not sure what they are inside the match expression

https://wiki.call-cc.org/man/3/Pattern%20matching

This is the docs, I don't quite understand it yet so maybe someone can help me with an example for what I am trying to do.


Solution

  • Several things here:

    If you really must pass in the pattern dynamically, you could do something like this:

    (use matchable)
    
    ;; Define patt to be available at the macro expansion level
    (define-for-syntax patt '('and (X Y) Z))
    
    ;; Make a macro that *expands* to the desired match form
    (define-syntax match-patt
      (ir-macro-transformer
         (lambda (e i c)
            `(match ,(cadr e)
               (,(i patt) (list ,(i 'X) ,(i 'Y) ,(i 'Z)))))))
    
    ;; Actually call the macro to generate the expression
    (define prop '(and (#t #t) #t))
    (match-patt prop)
    

    Of course this still can only work if the pattern is known at compile-time, so this doesn't really buy you anything unless you're doing really fancy things like reading the pattern at compile-time from a file or something.

    When programming in a Lisp (or Scheme), you must always keep in mind at which level of the expansion process you are programming. Usually there are two levels: compile-time and run-time. Macros expand into code at compile-time, so you can never get a macro to operate on information that's available at run-time.

    Of course, you could also generate the match expression using eval. Evaluated code again runs in two phases: macro-expansion occurs first, and running the code happens after that. But because you do this all from within a running program, you can inject expressions that were determined at run-time into eval.