Confused in macro definition

I want to implement lazy thread in SICP 3.5.1 section

First, I defined these two functions

(defmacro delay (form) `(lambda () ,form)) (defun force (form) (when form (funcall form))) 

When we called:

 (force (delay '(+ 1 2))) ;;=> (+ 1 2) (force (delay (+ 1 2))) ;;=> 3 

It happened. Then I continue to define the "cons-cons", but this time it appears in two ways:

 (defmacro stream-cons (ab) `(cons ,a ,(delay b))) (defmacro stream-cons (ab) `(cons ,a (delay ,b))) 

I do not think they are different, but I am wrong! The first edition, which is the wrong edition when called:

 (force (cdr (stream-cons 'a (progn (print "hello") 2)))) ;;=> (PROGN (PRINT "hello") 2) (macroexpand '(stream-cons 'a (progn (print "hello") 2))) ;;=> (CONS 'A #<CLOSURE (LAMBDA # :IN STREAM-CONS) {25ABB3A5}>) 

and the second edition, which is correct when called:

 (force (cdr (stream-cons 'a (progn (print "hello") 2)))) ;; ;; "hello" ;; => 2 (macroexpand '(stream-cons 'a (progn (print "hello") 2))) ;;=> (CONS 'A (DELAY (PROGN (PRINT "hello") 2))) 

Now I am very confused. Who can kindly help me clarify the different of the two? Thank you very much!

My environment: Windows 32bits, SBCL 1.1.4

+4
source share
1 answer

This is an important concept for understanding macros.

The fact is that ,(delay b) is estimated at the time of macro expansion, i.e. lambda is created in place and wrapped over the literal passed to it, which is a list of characters. This way you get a constant function that always returns the same value - the list that is your code.

You can do the following:

 ,(delay '(progn (print "hello") 2)) => (lambda () '(progn (print "hello") 2)) 

In the second option (delay ,b) :

 (delay ,'(progn (print "hello") 2)) => (delay (progn (print "hello") 2)) 

The trap here is that macro message arguments are passed literally, without evaluation. Thus, delay gets an efficiently quoted list ( '(progn (print "hello") 2) ). Which comma cancels the quote if they occur.

+7
source

Source: https://habr.com/ru/post/1483505/


All Articles