At 03:24 AM 1/15/2003, feilong wrote:
>Hello,freinds:
>Just now i have tried to get the length of (length (quote quote)),but i get the error...
> ...
>I have not very understood, (length (quote '(1 2 3))) is 2, (length (quote quote)) should be also 2, ...
The first step in determining the value of a Lisp expression is to
remove shorthand artifacts like "'" to see the actual s-expression that will
be evaluated.
In the case of (length (quote quote))
the internal for is also (length (quote quote))
In the case of (length (quote '(1 2 3)))
the internal form is (length (quote (quote (1 2 3))))
The full rules of evaluation are listed in CLtL. This is how the
expression (length (quote quote)) is evaluated:
(length (quote quote))
--4-- --5--
---2-- ------3------
----------1-----------
1. The item to be evaluated is a list.
2. Examine the first element of the list,
in this case -2- is the symbol length.
The symbol length is not the name of a special form,
hence -1- is a function call to the function named by -2-.
3. To evaluate a function call, first evaluate all the
arguments, in this case there is one argument, the list -3-.
4. Now we recurse on the definition: to evaluate the list -3-
we look at the first element of the list, -4- is the symbol quote.
The symbol quote is the name of a special form.
The result of evaluating special a form beginning with quote
is always the second itme in the list.
In this case this is -5-, the symbol quote.
Hence the one argument in the function call -1- is the symbol quote
The symbol quote is not a list, hence the function length signals an error.
Now the longer example:
(length (quote (quote (1 2 3))))
--4-- ------5--------
---2-- -----------3-----------
----------------1---------------
Note how it decomposes exactly like the previous example.
In this case the argument to length ends up being the list -5-
which turns out to be a list of two items.
>Why is the begin of definition of makro almost list operator. For example own definition my-if
>(defmacro my-if (test then else)
> (list '(cond (list test then) (list 't else))) ;;part1
>
>Can I so define the body of macro: (cond (test then) (t else));;part2
>while i thinkd part1 is equivalent to part2, can man replace part1 with part2? What is the difference?...
In your example, part1 and part2 are very different.
The body of function definition returns a value, this is the
value of the function call.
The body of a macro definition returns an expression which is then
evaluated to produce a value. In other words, the result returned
by the body of the macro definition is another program.
The body of the macro you call part1 returns a valid Lisp expression
(ie a valid Lisp program). The body of the my-if(part1) macro simply
re-arranges the text of the program to spell out a different Lisp
program that does what you want. To understand what a macro does,
imagine writing the result of the macro body in the your program
instead of the macro call.
If you define the macro as in part2
(defmacro my-if2 (test then else) (cond (test then) (t else)))
we still have a valid Lisp macro - the result returned by the
body of the macro definition is still a valid Lisp program, but
the meaning is very different:
writing (my-if2 t (+ x y) (- x y)) is equivalent to writing (+ x y)
writing (my-if2 nil (+ x y) (- x y)) is equivalent to writing (- x y)
writing (my-if2 (< x 0) (+ x y) (- x y)) is equivalent to writing (+ x y)
This last example illustrates more clearly the difference between a macro
call and a function call. The body of the macro looks at the source forms
of the program, not at the results computed by these forms. The macro my-if2
expands to the third or fourth item in the list depending on what the second
item in the list LOOKS like.