Monday, November 30, 2009

The importance of quasiquote

If you were like me and skipped through most of the chapter on quote, quasiquote and splicedquote, then you made a bad mistake. This part is particularily important as the whole macro business is dependent on this. So here's a refresher.

Very simply put quote just quotes its arguments. So, when we execute the following, we get the output as test.



(import (rnrs))

(define foo 'test)
(display foo)

Quasiquote allows us to do more. It allows us have a template which we can fill in with values. Consider the following.


(import (rnrs))

(define x 10)
(display `(list x ,x))

The output will be (list x 10). However, the advantage of quasiquote goes much beyond just templates. We can use it to debug our code better. 



(import (rnrs))

(define (fact n)
(cond
((or (= n 0) (= n 1)) n)
(else (* n (fact (- n 1))))))

(display (fact 5))
Now, we want to understand how fact works. So, let us re-write fact not to compute the value but to just print out the expanded s-expressions.

(import (rnrs))

(define (fact n)
(cond
((or (= n 0) (= n 1)) n)
(else `(* ,n ,(fact (- n 1))))))

(display (fact 5))

Now the output is more interesting - (* 5 (* 4 (* 3 (* 2 1)))). What quasiquote and unquote ended up showing us is how the expression is calculated. Now, the fact example is trivial but it does give us an insight into the computation involved. 

Related to quote is spliced-quote. If we use spliced-quote then the output of a list is expanded. So, 



(import (rnrs))

(define foo `(1 ,@(list 2 3)))
(define bar `(1 (list 2 3)))

(display foo)
(newline)
(display bar)
(newline)

 will give us the output as (1 2 3) and (1 (list 2 3)).

No comments: