Re: and vs. and (newbie question)
- From: Peter Seibel <peter@xxxxxxxxxxxxxxx>
- Date: Sun, 21 Aug 2005 23:03:40 GMT
Karstens Rage <karstens@xxxxxxxx> writes:
> I had a hard time searching for this on the newsgroups since and is not
> considered a keyword. I am trying to learn LISP and I came across a very
> confusing issue (for me anyway).
>
> There is an example in "Common Lisp" by David Touretzky that I just dont
> get.
>
> In Chapter 4 Advanced Topic he talks about Boolean functions. The
> example is:
>
> (defun logical-and (x y) (and x y t))
>
> and then shows:
>
> (logical-and 'tweet 'woof) -> t
>
> and
>
> (and 'tweet 'woof) -> woof
>
> I completely understand that that last to evaluate as non-nil is
> returned and in the first case the "t" is evaluated last and in the
> second 'woof is evaluated last.
>
> But then he goes on to show:
>
> (and (numberp 'fred) (oddp 'fred)) -> nil
>
> but
>
> (logical-and (numberp 'fred) (oddp 'fred)) -> generates an error from
> oddp. And sure enough it does.
>
> Why is the and in logical-and any different than the and not in logical
> and? I.e. why does (oddp 'fred) evaluate when (numberp 'fred) has
> already evaluated to nil?
It's not the difference between the AND in LOGICAL-AND any any other
AND; it's because LOGICAL-AND is a functon while AND is a macro.
Because LOGICAL-AND is a function so all of its arguments are
evaluated before the function is called. In other words to evaluate:
(logical-and (+ 1 2) (+ 3 4))
Lisp first evaluates (+ 1 2) and gets 3. Then it evaluates (+ 3 4) and
gets 7. Then it passes those two values as arguments to LOGICAL-AND
here they are dealt with by the AND. However when you try to evaluate:
(logical-and (numberp 'fred) (oddp 'fred))
it first evaluates (NUMBERP 'FRED) which evaluates to NIL and then
tries to evaluate (ODDP 'FRED) which barfs. Thus LOGICAL-AND is never
called.
AND, on the other hand, being a macro, is expanded wherever it occurs
anything is evaluated (well before if the code using it is
compiled). Thus when you write:
(and (numberp 'fred) (oddp 'fred))
it's as if you had written something like:
(cond ((not (numberp 'fred)) nil) (t (oddp 'fred)))
which obviously takes care not to evaluate (ODDP 'FRED) unless
(NUMBERP 'FRED) has evaluated to true. But that does no good when the
AND is part of a function because the function arguments have already
been evaluated.
-Peter
--
Peter Seibel * peter@xxxxxxxxxxxxxxx
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp * http://www.gigamonkeys.com/book/
.
- References:
- and vs. and (newbie question)
- From: Karstens Rage
- and vs. and (newbie question)
- Prev by Date: Re: Lisp's QUOTE and Mathematica's "Hold"
- Next by Date: Re: and vs. and (newbie question)
- Previous by thread: and vs. and (newbie question)
- Next by thread: Re: and vs. and (newbie question)
- Index(es):
Relevant Pages
|