Search code examples
schemeracketquoteminikanren

How to use quote and unquote to more faithfully translate The Reasoned Schemer into Racket?


(Details of my miniKanren in Racket setup appear at the bottom[1].)

The way quotes and unquotes work in The Reasoned Schemer appears not to match the way they work in Racket. For instance, verse 2 of chapter 2 suggests[2] the following function definition:

(run #f
     (r )
     (fresh (y x )
            (== '(,x ,y) r )))

If I evaluate that, I get '((,x ,y)). If instead I rewrite it as this:

(run #f
     (r )
     (fresh (y x )
            (== (list x y) r)))

I get the expected result, '((_.0 _.1)).

This might seem like a minor problem, but in many cases the required translation is extremely verbose. For instance, in exercise 45 of chapter 3 (page 34), the book provides, roughly[3] the following definition:

(run 5 (r)
     (fresh (w x y z)
            (loto (('g 'g) ('e w) (x y) . z))
            (== (w (x y) z) r)))

In order to get the results they get, I had to rewrite it like this:

(run 5 (r)
     (fresh (w x y z)
            (loto (cons '(g g)
                        (cons (list 'e w)
                              (cons (list x y)
                                    z))))
            (== (list w (list x y) z)
                r)))

[1] As described here, I ran raco pkg install minikanren and then defined a few missing pieces.

[2] Actually, they don't write precisely that, but if you heed the advice in the footnotes to that verse and an earlier verse, it's what you get.

[3] Modulo some implicit quoting and unquoting that I cannot deduce.


Solution

  • Use the backquote ` instead of the simple quote ' you have been using.