Hi all, i have played around the reduce function for a while...
just curious, why following input can't work??
it looks perfectly resonable to use "and" as the function call in reduce....
--------------Test 1---------------------------
>>(reduce 'and '( t t nil))
Error: T is not of type LIST.
Fast links are on: do (si::use-fast-links nil) for debugging
Error signalled by AND.
Backtrace: system:universal-error-handler > evalhook > reduce > AND
--------------Test 2----------------------------
>>(reduce 'and '(t))
T
--------------------------------------------------
Seems it can't take more than two more than 2 arguments in input list.....
"stevenlien" <··········@yahoo.com> writes:
> Hi all, i have played around the reduce function for a while...
>
> just curious, why following input can't work??
> it looks perfectly resonable to use "and" as the function call in reduce....
No, and is a macro, not a function
--
Johan Ur Riise
90 15 77 78
"stevenlien" <··········@yahoo.com> wrote in message news:<·······················@news02.bloor.is.net.cable.rogers.com>...
> Hi all, i have played around the reduce function for a while...
>
> just curious, why following input can't work??
> it looks perfectly resonable to use "and" as the function call in reduce....
>
> --------------Test 1---------------------------
> >>(reduce 'and '( t t nil))
>
If you want to reduce with and, you need a version of and that is:
1. a function, not a macro.
2. can take zero args (as required by reduce).
(defun and* (&optional a b)
(if (null a) nil
(not (null b))))
now you can do:
(reduce #'and* '())
=> nil
or
(reduce #'and* '(t t t nil t))
=> nil
or
(reduce #'and* '(t t t t t))
=> t
> If you want to reduce with and, you need a version of and that is:
>
> 1. a function, not a macro.
> 2. can take zero args (as required by reduce).
>
> (defun and* (&optional a b)
> (if (null a) nil
> (not (null b))))
I don't think this is quite right. In particular,
(reduce #'and* '())
=> nil
seems wrong.
It's not quite as easy as it looks.
I think it should be something like this:
(defun and* (&rest a)
(cond ((null a) (and))
(t (and (car a) (apply #'and* (cdr a))))))
* (reduce #'and* '(t t t nil t))
NIL
* (reduce #'and* '(t t t t t))
T
* (reduce #'and* '())
T
You want the and-like behavior with no arguments:
* (and*)
T
Note that neither of these two versions of and* are short-circuiting,
which is one reason to use a macro version.
* (and* nil (print "Ha!"))
"Ha!"
NIL
--
Fred Gilham ······@csl.sri.com
Communism is a murderous failure.
Socialism is communism with movie stars.
Fred Gilham <······@snapdragon.csl.sri.com> wrote in message news:<··············@snapdragon.csl.sri.com>...
> > If you want to reduce with and, you need a version of and that is:
> >
> > 1. a function, not a macro.
> > 2. can take zero args (as required by reduce).
> >
> > (defun and* (&optional a b)
> > (if (null a) nil
> > (not (null b))))
>
> I don't think this is quite right. In particular,
>
> (reduce #'and* '())
> => nil
>
> seems wrong.
The truth value of '() is nil (i.e., in common lisp, the emty list is
false). From the spec:
"nil n. the object that is at once the symbol named "NIL" in the
COMMON-LISP package, the empty list, the boolean (or generalized
boolean) representing false, and the name of the empty type."
so:
(and '()) => nil
(and '() t) => nil
So (reduce #'and* '()) => nil is what one would expect.
BTW, I am, of course aware of the existence of every and some, but the
OP may want to write a function that uses reduce and takes a function
as an argument, in which case he would have to special case and, to
use every instead, and similarly for or and some.
> The truth value of '() is nil (i.e., in common lisp, the emty list
> is false). From the spec:
Yes, but...
You aren't applying "and" to anything when you give an empty list to
reduce. You aren't giving the value nil to "and". You are just giving
it nothing.
Look at this:
* (reduce #'+ '())
0
* (+ nil)
nil
Hmn, I expected an error. I don't think CMUCL is doing that one
right...
Let's try CLISP:
[2]> (+ nil)
*** - argument to + should be a number: NIL
1. Break [3]>
[4]> (+)
0
Same for CMUCL:
* (+)
0
I think you can see what I'm getting at. Reduce on an empty list
doesn't give nil as an argument to the function. It gives no
arguments to the function. If it were passing nil to the function,
then (reduce #'+ '()) would either give nil or an error, depending on
your Lisp implementation. But it gives 0.
"And" with no arguments gives t:
[5]> (and)
T
So
(reduce #'and* '())
should also produce t.
--
Fred Gilham ······@csl.sri.com
I can't escape the sensation that I have already been thinking in Lisp
all my programming career, but forcing the ideas into the constraints
of bad languages, which explode those ideas into a bewildering array
of details, most of which are workarounds for the language.
--Kaz Kylheku
In article <·················@paloalto-snr1.gtei.net>,
Barry Margolin <······@genuity.net> wrote:
> That's irrelevant, because there's no NIL in that list. It's an empty list
> that's being reduced over.
and
In article <··············@snapdragon.csl.sri.com>,
Fred Gilham <······@snapdragon.csl.sri.com> wrote:
> (reduce #'and* '())
>
> should also produce t.
OK, I see now, sorry. As Barry points out, I was mistakenly thinking
that (reduce #'some-function '()) was working on the single element nil,
rather than no elements at all. As you point out, (and) => t, while I
was mistakenly thinking of (and '()) which returns nil.
> * (+ nil)
> nil
> Hmn, I expected an error. I don't think CMUCL is doing that one
> right...
For the curious (like I was):
The spec says + "Might signal type-error if some argument is not a
number." So CMUCL's okay.
Under the hood, it has a function named TWO-ARG-+ that deals with
two-argument + calls, and handles all other cases in a manner similar
to REDUCE:
(defmacro define-arith (op init doc)
`(defun ,op (&rest args)
,doc
(if (null args) ,init
(do ((args (cdr args) (cdr args))
(res (car args) (,op res (car args))))
((null args) res)))))
(define-arith + 0
"Returns the sum of its arguments. With no args, returns 0.")
So a one-arg + gets optimized into just its argument:
* (+ 'foo)
FOO
Cheers,
joelh
In article <····························@posting.google.com>,
Raffael Cavallaro <·······@mediaone.net> wrote:
>Fred Gilham <······@snapdragon.csl.sri.com> wrote in message
>news:<··············@snapdragon.csl.sri.com>...
>> > If you want to reduce with and, you need a version of and that is:
>> >
>> > 1. a function, not a macro.
>> > 2. can take zero args (as required by reduce).
>> >
>> > (defun and* (&optional a b)
>> > (if (null a) nil
>> > (not (null b))))
>>
>> I don't think this is quite right. In particular,
>>
>> (reduce #'and* '())
>> => nil
>>
>> seems wrong.
>
>The truth value of '() is nil (i.e., in common lisp, the emty list is
>false). From the spec:
That's irrelevant, because there's no NIL in that list. It's an empty list
that's being reduced over.
In general, (reduce <function> '()) should return the identity for the
function. So (reduce #'and* '()) should return T, and (reduce #'or* '())
should return NIL. You can arrange for this by using the :initial-value
keyword argument.
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
·······@mediaone.net (Raffael Cavallaro) writes:
> So (reduce #'and* '()) => nil is what one would expect.
What I would expect is
(reduce #'and* ()) == (and*) == (and) => t
--
Frode Vatvedt Fjeld
In article <··············@vserver.cs.uit.no>,
Frode Vatvedt Fjeld <······@cs.uit.no> wrote:
> ·······@mediaone.net (Raffael Cavallaro) writes:
>
> > So (reduce #'and* '()) => nil is what one would expect.
>
> What I would expect is
>
> (reduce #'and* ()) == (and*) == (and) => t
I think you have a basic misunderstanding of reduce. Reduce is *not*
supposed to return the function which is it's first argument, but rather
the "result of [a] function's being applied to successive pairs of
elements of [a]sequence." There may be a pathological case if you write
a function which returns itself when called with 0 values, but
otherwise, never. Your interpretation also leads me to suspect that you
misunderstand the role of functional arguments in much of common lisp.
They are generally specified as the engine, or transformation, which
will operate within the function, not as data that will be operated on
itself.
From the spec:
"In the normal case, the result of reduce is the combined result of
function's being applied to successive pairs of elements of sequence. If
the subsequence contains exactly one element and no initial-value is
given, then that element is returned and function is not called. If the
subsequence is empty and an initial-value is given, then the
initial-value is returned and function is not called. If the subsequence
is empty and no initial-value is given, then the function is called with
zero arguments, and reduce returns whatever function does. This is the
only case where the function is called with other than two arguments. "
In other words, reduce never returns the function which is it's first
argument. It always returns either
1. the result of the *application* of that funcion to successive pairs
of elements of sequence.
2. The sole element of sequence (if no initial-value is given).
3. The initial value (if the sequence is empty).
4. The result of calling the function with zero args.
Note that none of these cases is the function itself, so...
(reduce #'and* ())) => (and* ()) => nil
Raffael Cavallaro <················@junk.mail.me.not.mac.com> writes:
> In article <··············@vserver.cs.uit.no>,
> Frode Vatvedt Fjeld <······@cs.uit.no> wrote:
>
> > ·······@mediaone.net (Raffael Cavallaro) writes:
> >
> > > So (reduce #'and* '()) => nil is what one would expect.
> >
> > What I would expect is
> >
> > (reduce #'and* ()) == (and*) == (and) => t
>
> I think you have a basic misunderstanding of reduce. Reduce is *not*
> supposed to return the function which is it's first argument
[snip]
Just because you're spewing bile back and forth in another thread is
no excuse to apply the least favorable interpretation possible to
someone's words in this thread.
Look at what he wrote again. The first form is equivalent to the
second, which is equivalent to the third, which yeilds T.
Before you accuse someone of having "basic misunderstanding"s (which
in this context is fairly insulting), perhaps you should calm down and
reread what they wrote assuming they're not stupid.
> In other words, reduce never returns the function which is it's first
> argument. It always returns either
[snip]
> 4. The result of calling the function with zero args.
Right, and what happens when you call AND with zero args?
> Note that none of these cases is the function itself, so...
>
> (reduce #'and* ())) => (and* ()) => nil
No, (reduce #'and* ()) is the same as (and*), not (and* nil)!
--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'
In article <···············@whirlwind.OCF.Berkeley.EDU>,
···@whirlwind.OCF.Berkeley.EDU (Thomas F. Burdick) wrote:
> Before you accuse someone of having "basic misunderstanding"s (which
> in this context is fairly insulting), perhaps you should calm down and
> reread what they wrote assuming they're not stupid.
Yeah, I did that, and superseded the article to which you're replying.
Sorry you had to read it.
As for my assumptions, I was quite calm when I wrote that post, and
really quite mystified at what I took to be a pretty obvious mistake. Of
course, it was on my part, not Frode's.
In article <··············@vserver.cs.uit.no>,
Frode Vatvedt Fjeld <······@cs.uit.no> wrote:
> ·······@mediaone.net (Raffael Cavallaro) writes:
>
> > So (reduce #'and* '()) => nil is what one would expect.
>
> What I would expect is
>
> (reduce #'and* ()) == (and*) == (and) => t
Yes, I was mistakenly thinking that reduce was operating on nil, rather
than on an empty list.
I.e, (and) => t, which is what we're dealing with here, not
(and '()) => which is what, as Barry points out, I was mistakenly
thinking of.
"Raffael Cavallaro" <·······@mediaone.net> wrote in message
·································@posting.google.com...
> Fred Gilham <······@snapdragon.csl.sri.com> wrote in message
news:<··············@snapdragon.csl.sri.com>...
> > > If you want to reduce with and, you need a version of and that is:
> > >
> > > 1. a function, not a macro.
> > > 2. can take zero args (as required by reduce).
> > >
> > > (defun and* (&optional a b)
> > > (if (null a) nil
> > > (not (null b))))
> >
> > I don't think this is quite right. In particular,
> >
> > (reduce #'and* '())
> > => nil
> >
> > seems wrong.
>
> The truth value of '() is nil (i.e., in common lisp, the emty list is
> false). From the spec:
>
...
> (and '()) => nil
> (and '() t) => nil
The relevant examples are:
CL-USER 1 > (and)
T
CL-USER 2 > (or)
NIL
So (reduce #'and* '()) => t is the right expectation.
--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
In article <····························@posting.google.com>,
Raffael Cavallaro <·······@mediaone.net> wrote:
>"stevenlien" <··········@yahoo.com> wrote in message
>news:<·······················@news02.bloor.is.net.cable.rogers.com>...
>> Hi all, i have played around the reduce function for a while...
>>
>> just curious, why following input can't work??
>> it looks perfectly resonable to use "and" as the function call in reduce....
>>
>> --------------Test 1---------------------------
>> >>(reduce 'and '( t t nil))
>>
>
>If you want to reduce with and, you need a version of and that is:
BTW, no one has yet pointed out that there are already standard functions
that do what (reduce 'and ...) and (reduce 'or ...) would do if they did
what the OP expected: EVERY and SOME.
(every '(t t nil)) => NIL
(some '(t t nil)) => T
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin <······@genuity.net> writes:
>
> BTW, no one has yet pointed out that there are already standard functions
> that do what (reduce 'and ...) and (reduce 'or ...) would do if they did
> what the OP expected: EVERY and SOME.
>
> (every '(t t nil)) => NIL
> (some '(t t nil)) => T
Actually they need a function to apply:
(every #'identity '(t t nil)) => NIL
(some #'identity '(t t nil)) => T
--
Thomas A. Russ, USC/Information Sciences Institute ···@isi.edu
Barry Margolin <······@genuity.net> writes:
>
> BTW, no one has yet pointed out that there are already standard functions
> that do what (reduce 'and ...) and (reduce 'or ...) would do if they did
> what the OP expected: EVERY and SOME.
>
> (every '(t t nil)) => NIL
> (some '(t t nil)) => T
Actually, like reduce, they need a function to apply:
(every #'identity '(t t nil)) => NIL
(some #'identity '(t t nil)) => T
--
Thomas A. Russ, USC/Information Sciences Institute ···@isi.edu
Barry Margolin <······@genuity.net> wrote in message news:<···············@paloalto-snr1.gtei.net>...
> BTW, no one has yet pointed out that there are already standard functions
> that do what (reduce 'and ...) and (reduce 'or ...) would do if they did
> what the OP expected: EVERY and SOME.
>
> (every '(t t nil)) => NIL
> (some '(t t nil)) => T
Shouldn't that be:
(every #'identity '(t t nil)) = NIL
(some #'identity '(t t nil)) = T
or
(notany #'null '(t t nil)) => NIL
(notevery #'null '(t t nil)) => T
i.e., don't every & co. take two arguments, the first of which is a function?
FYI:
[8]> (every #'identity '())
T
[9]> (some #'identity '())
NIL
--
Fred Gilham ······@csl.sri.com
Ah, the 20th century, when the flight from reason crash-landed into
the slaughterhouse. --- James Ostrowski
Barry Margolin <······@genuity.net> writes:
> BTW, no one has yet pointed out that there are already standard
> functions that do what (reduce 'and ...) and (reduce 'or ...) would
> do if they did what the OP expected: EVERY and SOME.
>
> (every '(t t nil)) => NIL
> (some '(t t nil)) => T
Except that both of these take a predicate as their first parameter,
so what you presumably mean is
(every #'identity '(t t nil)) => NIL
(some #'identity '(t t nil)) => T
--
Frode Vatvedt Fjeld
* stevenlien wrote:
> it looks perfectly resonable to use "and" as the function call in reduce....
AND isn't a function. It isn't a function because it treats its
arguments specially. In particular it only evaluates as far as it
needs to. So:
(and nil (error "this is an error")) -> NIL.
--tim