From: Karstens Rage
Subject: and vs. and (newbie question)
Date: 
Message-ID: <u6adnU10iYYpnpTeRVn-qQ@comcast.com>
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?

k

From: nepheles
Subject: Re: and vs. and (newbie question)
Date: 
Message-ID: <1124667177.852600.96090@o13g2000cwo.googlegroups.com>
Karstens Rage wrote:
> ...
> 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?
> ...

The reason is that (and) is a macro, not a function: parameters to a
function are evaluated before the function itself is run, whereas a
macro is supplied with the raw s-expressions. These s-expressions
aren't evaluated until later (and sometimes not at all, as in this
case).

And so, as for (and) itself, it evaluates its arguments in left to
right order, _terminating whenever any evaluates to nil_. In the above
code, (numberp 'fred) evaluates to nil, meaning (oddp 'fred) is never
evaluated.

A simple definition of and might look something like:

(defmacro my-and (&rest tests)
   (when tests
     `(if ,(car tests)
          (my-and ,@(cdr tests)))))

(my-and (numberp 'fred) (oddp 'fred))

would expand to

(if (numberp 'fred) (oddp 'fred))

Here, of course, the "true" branch of the (if) form is never evaluated.
We can happily evaluate stuff like (my-and 'foo nil (/ 1 0)), and never
get an error.

(logical-and), on the other hand, is defined as an ordinary function
(that happens to use the (and) macro internally). Like any other
function, it never sees the s-expression form of its arguments: only
their values. In general, regardless of the definition of a function,
an error will be signalled if any of its parameters is invalid.

(defun foo (&rest args))

(foo <anything>) will raise an error if any of the supplied parameters
do.

Hopefully this will make things clearer.
From: Peter Seibel
Subject: Re: and vs. and (newbie question)
Date: 
Message-ID: <m2hddivqnm.fsf@gigamonkeys.com>
Karstens Rage <········@rage.com> 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           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Stefan Schmiedl
Subject: Re: and vs. and (newbie question)
Date: 
Message-ID: <opsvvshkq6ltg9bq@g64.xss.de>
On Sun, 21 Aug 2005 15:44:03 -0700, Karstens Rage <········@rage.com> wrote:

>
> (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?


and is a special form, as macroexpanding it shows (in sbcl)

(IF (NUMBERP 'A) (AND (ODDP 'A)) NIL)

so here oddp is only executed if numberp was already successful.

logical-and, however, is a "normal" function, which is called with
the *evaluated* arguments, i.e. *after* calling both numberp and oddp.

hth,
s.
From: Tayssir John Gabbour
Subject: Re: and vs. and (newbie question)
Date: 
Message-ID: <1124670153.929504.86820@g14g2000cwa.googlegroups.com>
Stefan Schmiedl wrote:
> On Sun, 21 Aug 2005 15:44:03 -0700, Karstens Rage <········@rage.com> wrote:
> > (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?
>
> and is a special form, as macroexpanding it shows (in sbcl)

Actually, AND is not a "special form", but rather a macro. Here's some
relevant parts of the hyperspec, which I'm sure will provide effective
bedtime reading.
http://www.lispworks.com/documentation/HyperSpec/Body/m_and.htm
http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#special_form
http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_o.htm#operator


Tayssir