From: stevenlien
Subject: About reduce funciton
Date: 
Message-ID: <AVHm9.125143$q41.109602@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))

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.....

From: Johan Ur Riise
Subject: Re: About reduce funciton
Date: 
Message-ID: <8765wkligk.fsf@egg.topp.dyndns.com>
"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
From: Raffael Cavallaro
Subject: Re: About reduce funciton
Date: 
Message-ID: <aeb7ff58.0210021945.25d8348d@posting.google.com>
"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
From: Fred Gilham
Subject: Re: About reduce funciton
Date: 
Message-ID: <u7heg3y6s3.fsf@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.

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.
From: Raffael Cavallaro
Subject: Re: About reduce funciton
Date: 
Message-ID: <aeb7ff58.0210031053.7388a214@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:

"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.
From: Fred Gilham
Subject: Re: About reduce funciton
Date: 
Message-ID: <u7y99f3uq7.fsf@snapdragon.csl.sri.com>
> 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
From: Raffael Cavallaro
Subject: Re: About reduce funciton
Date: 
Message-ID: <raffaelcavallaro-ED4AD4.21584003102002@netnews.attbi.com>
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.
From: Joel Ray Holveck
Subject: Optimizing + (Was: Re: About reduce funciton)
Date: 
Message-ID: <y7cn0ptoqkd.fsf_-_@sindri.juniper.net>
> * (+ 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
From: Barry Margolin
Subject: Re: About reduce funciton
Date: 
Message-ID: <RF0n9.26$sf4.1547@paloalto-snr1.gtei.net>
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.
From: Frode Vatvedt Fjeld
Subject: Re: About reduce funciton
Date: 
Message-ID: <2helb7e420.fsf@vserver.cs.uit.no>
·······@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
From: Raffael Cavallaro
Subject: Re: About reduce funciton
Date: 
Message-ID: <raffaelcavallaro-3A02DE.21312103102002@netnews.attbi.com>
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
From: Thomas F. Burdick
Subject: Re: About reduce funciton
Date: 
Message-ID: <xcv3crnge5n.fsf@whirlwind.OCF.Berkeley.EDU>
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!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Raffael Cavallaro
Subject: Re: About reduce funciton
Date: 
Message-ID: <raffaelcavallaro-D10133.23483103102002@netnews.attbi.com>
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.
From: Raffael Cavallaro
Subject: Re: About reduce funciton
Date: 
Message-ID: <raffaelcavallaro-63E2AA.22045703102002@netnews.attbi.com>
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.
From: Coby Beck
Subject: Re: About reduce funciton
Date: 
Message-ID: <anilqf$10fu$1@otis.netspace.net.au>
"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")
From: Barry Margolin
Subject: Re: About reduce funciton
Date: 
Message-ID: <VqYm9.8$sf4.647@paloalto-snr1.gtei.net>
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.
From: Thomas A. Russ
Subject: Re: About reduce funciton
Date: 
Message-ID: <ymid6qrcuzl.fsf@sevak.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 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    
From: Thomas A. Russ
Subject: Re: About reduce funciton
Date: 
Message-ID: <ymibs6bcuye.fsf@sevak.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    
From: Raffael Cavallaro
Subject: Re: About reduce funciton
Date: 
Message-ID: <aeb7ff58.0210031122.7d7265f7@posting.google.com>
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?
From: Fred Gilham
Subject: Re: About reduce funciton
Date: 
Message-ID: <u7vg4j3um3.fsf@snapdragon.csl.sri.com>
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
From: Frode Vatvedt Fjeld
Subject: Re: About reduce funciton
Date: 
Message-ID: <2hofabea7c.fsf@vserver.cs.uit.no>
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
From: Tim Bradshaw
Subject: Re: About reduce funciton
Date: 
Message-ID: <ey3wup0sela.fsf@cley.com>
* 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