Reputation: 193
Why does and
operator returns a value? What is the returned value dependent on?
When I try the following example -
(write (and a b c d)) ; prints the greatest integer among a b c d
where a
, b
, c
and d
are positive integers, then and
returns the greatest of them.
However when one of a
, b
, c
and d
is 0 or negative, then the smallest integer is returned. Why is this the case?
Upvotes: 1
Views: 140
Reputation: 58627
and
can be regarded as a generalization of the two-place if
. That is to say, (and a b)
works exactly like (if a b)
. With and
in the place of if
we can add more conditions: (and a1 a2 a3 a4 ... aN b)
. If they all yield true, then b
is returned. If we use if
to express this, it is more verbose, because we still have to use and
: (if (and a1 a2 a3 ... aN) b)
. and
also generalizes in that it can be used with only one argument (if
cannot), and even with no arguments at all (yields t
in that case).
Mathematically, and
forms a group. The identity element of that group is t
, which is why (and)
yields t
. To describe the behavior of the N-argument and
, we just need these rules:
(and) -> yield t
(and x y) -> { if x is true evaluate and yield y
{ otherwise yield nil
Now it turns out that this rule for a two-place and
obeys the associative law: namely (and (and x y) z)
behaves the same way as (and x (and y z))
. The effect of the above rules is that no matter in which of these two ways we group the terms in this compound expression, x
, y
, and z
are evaluated from left to right, and evaluation either stops at the first nil
which it encounters and yields nil
, or else it evaluates through to the end and yields the value of z
.
Thus because we have this nice associative property, the rational thing to do in a nice language like Lisp which isn't tied to infix operators is to recognize that since the associative grouping doesn't matter, let's just have the flat syntax (and x1 x2 x3 ... xN)
, with any number of arguments including zero. This syntax denotes any one of the possible associations of N-1
binary and
s which all yield the same behavior.
In other words, let's not make the poor programmer write a nested (and (and (and ...) ...) ...)
to express a four-term and
, and just let them write (and ...)
with four arguments.
Summary:
and
yields t
, which has to do with t
being the identity element for the and
operation.and
yields the second value if the first one is true. This is a useful equivalence to the two-place if. Binary and
could be defined as yielding t
when both arguments are true, but that would be less useful. In Lisp, any value that is not nil
is a Boolean true. If we replace a non-nil
value with t
, it remains Boolean true, but we have lost potentially useful information.and
is a consequence of the associative property; or rather preserving the equivalence between the flat N-argument form and all the possible binary groupings which are already equivalent to each other thanks to the associative property.if
, like (if cond1 cond2 cond3 cond4 ... condN then-form)
, where then-form
is evaluated and yielded if all the conditions are true. We just have to spell if
using the and
symbol.Upvotes: 2
Reputation: 236124
As stated in the documentation:
The macro
and
evaluates each form one at a time from left to right. As soon as any form evaluates tonil
,and
returnsnil
without evaluating the remaining forms. If all forms but the last evaluate totrue
values, and returns the results produced by evaluating the last form. If no forms are supplied,(and)
returnst
.
So the returned value doesn't depend on which value is the "greatest" or "smallest" of the arguments.
Upvotes: 7