From: Stephan Kepser
Subject: Behaviour of MAPCAR
Date: 
Message-ID: <3udfe7$66h@sparcserver.lrz-muenchen.de>
Hi,

when debugging my program I discovered the following behaviour of MAPCAR  
(in Lucid CommonLisp v.4.1.1), which astonished me:

>(mapcar #'(lambda (x) '*a*) '(a b)
(*a* *a*)

>(mapcar #'(lambda (x) '*a*) '(a . b)
(*a*)

The first operation, the one on true (i.e. non-dotted) lists, works as  
expected. But what about the second? Obviously, the function (lambda (x)  
'*a*) is only applied to the car of (a . b). Since the cdr is a non-NIL  
element, one may (and indeed I did) have expected that the function is  
applied to the cdr, too.
When discussing mapping functions (7.8.4, p. 171 ff), CLtL2 only speaks  
about lists, no special reference to true lists or dotted lists. And what  
mapcar is suppossed to do with the end of a list, is - in my eyes - open  
to interpretation. All, that said is

	First the function is applied to the car of each list,
	then to the cadr of each list, and so on. 
	                             (CLtL2, p.171)

So "and so on" till what? The explanation seems to imply that mapcar is  
supposed to work on true lists. But no such restriction is explicitly  
made.


How should things work? Could someone please explain.

Stephan.

--
Stephan Kepser           ······@cis.uni-muenchen.de
CIS   Centrum fuer Informations- und Sprachverarbeitung
LMU Muenchen, Wagmuellerstr. 23/III, D-80538 Muenchen,  Germany
Tel: +49 +89/2110666     Fax: +49 +89/2110674

From: Carl L. Gay
Subject: Re: Behaviour of MAPCAR
Date: 
Message-ID: <CGAY.95Jul17090617@ix.cs.uoregon.edu>
   From: ······@cis.uni-muenchen.de (Stephan Kepser)
   Date: 17 Jul 1995 10:52:55 GMT

   when debugging my program I discovered the following behaviour of MAPCAR  
   (in Lucid CommonLisp v.4.1.1), which astonished me:

   >(mapcar #'(lambda (x) '*a*) '(a b)
   (*a* *a*)

   >(mapcar #'(lambda (x) '*a*) '(a . b)
   (*a*)
...
   When discussing mapping functions (7.8.4, p. 171 ff), CLtL2 only speaks  
   about lists, no special reference to true lists or dotted lists. And what  
   mapcar is suppossed to do with the end of a list, is - in my eyes - open  
   to interpretation. All, that said is

	   First the function is applied to the car of each list,
	   then to the cadr of each list, and so on. 
					(CLtL2, p.171)

I would expect an error in the second case, since the second argumnt
isn't a list and the doc for mapcar sez it must be.  Ah, I just
checked, and in Allegro 4.2 this is indeed what I get.

   So "and so on" till what? The explanation seems to imply that mapcar is  
   supposed to work on true lists. But no such restriction is explicitly  
   made.

The last sentence on page 30 reads "throughout this book, unless
otherwise specified, it is an error to pass a dotted list to a
function that is specified to require a list as an argument."

Looks to me like a bug report to Lucid might be in order, if 4.1.1 is
the latest and greatest.

-Carl
From: Barry Margolin
Subject: Re: Behaviour of MAPCAR
Date: 
Message-ID: <3uevpg$pr6@tools.near.net>
In article <··················@ix.cs.uoregon.edu> ····@ix.cs.uoregon.edu (Carl L. Gay) writes:
>Looks to me like a bug report to Lucid might be in order, if 4.1.1 is
>the latest and greatest.

Of course, he means "a bug report to Harlequin".  Lucid wouldn't cons if
you put 10,000 volts through it -- it is an EX-vendor.
-- 
Barry Margolin
BBN Planet Corporation, Cambridge, MA
······@bbnplanet.com
Phone (617) 873-3126 - Fax (617) 873-5124
From: Kevin Gallagher
Subject: Re: Behaviour of MAPCAR
Date: 
Message-ID: <3ugmum$q2j@kernighan.cs.umass.edu>
Carl L. Gay <····@ix.cs.uoregon.edu> writes:
>
>   From: ······@cis.uni-muenchen.de (Stephan Kepser)
>   Date: 17 Jul 1995 10:52:55 GMT
>
>   when debugging my program I discovered the following behaviour of MAPCAR  
>   (in Lucid CommonLisp v.4.1.1), which astonished me:
>
>   >(mapcar #'(lambda (x) '*a*) '(a b)
>   (*a* *a*)
>
>   >(mapcar #'(lambda (x) '*a*) '(a . b)
>   (*a*)
>...
>
>I would expect an error in the second case, since the second argumnt
>isn't a list and the doc for mapcar sez it must be.  Ah, I just
>checked, and in Allegro 4.2 this is indeed what I get.
>
>...
>Looks to me like a bug report to Lucid might be in order, if 4.1.1 is
>the latest and greatest.
>

At high optimization levels (e.g., speed 3, safety 1) many lisps will
not signal an error when given a dotted list in such situations.  This
is ok because "_it is an error_ to pass a dotted list ..." rather than
"and error is signaled when..."

The one that catches me occasionally is that (again, at high
optimization levels) some lisps treat unbound variables as non-nil, so
forms like when and cond will succeed!

Kevin Gallagher
From: Michael Tselman
Subject: Re: Behaviour of MAPCAR
Date: 
Message-ID: <3ue74e$4lr@camelot.ccs.neu.edu>
Stephan Kepser (······@cis.uni-muenchen.de) wrote:
: Hi,

: when debugging my program I discovered the following behaviour of MAPCAR  
: (in Lucid CommonLisp v.4.1.1), which astonished me:

: >(mapcar #'(lambda (x) '*a*) '(a b)
: (*a* *a*)

: >(mapcar #'(lambda (x) '*a*) '(a . b)
: (*a*)

: The first operation, the one on true (i.e. non-dotted) lists, works as  
: expected. But what about the second? Obviously, the function (lambda (x)  
: '*a*) is only applied to the car of (a . b). Since the cdr is a non-NIL  
: element, one may (and indeed I did) have expected that the function is  
: applied to the cdr, too.
: When discussing mapping functions (7.8.4, p. 171 ff), CLtL2 only speaks  
: about lists, no special reference to true lists or dotted lists. And what  
: mapcar is suppossed to do with the end of a list, is - in my eyes - open  
: to interpretation. All, that said is

: 	First the function is applied to the car of each list,
: 	then to the cadr of each list, and so on. 
: 	                             (CLtL2, p.171)

: So "and so on" till what? The explanation seems to imply that mapcar is  
: supposed to work on true lists. But no such restriction is explicitly  
: made.

: How should things work? Could someone please explain.

Read page 30 of CLtL2. In particular it says (last paragraph):
	"... Most functions advertised to operate on lists expect to be given
	true lists. Throughout this book, unless otherwise specified, it is
	an error to pass a dotted list to a function that is specified to
	require a list as an argument."


: Stephan.

: --
: Stephan Kepser           ······@cis.uni-muenchen.de
: CIS   Centrum fuer Informations- und Sprachverarbeitung
: LMU Muenchen, Wagmuellerstr. 23/III, D-80538 Muenchen,  Germany
: Tel: +49 +89/2110666     Fax: +49 +89/2110674

--
-----------------------------------------------------------------------------+
Michael Tselman (Misha)   Internet: ·····@ccs.neu.edu   | Imagination is     |
College of Computer Science, Northeastern University    |   more important   |
23 Cullinane Hall, 360 Huntington Ave., Boston, MA 02115|     than knowledge!|
Phone: (617)-373-3822,      Fax:  (617)-373-5121        |                    |
WWW: http://www.ccs.neu.edu/home/misha                  | (A. Einstein)      |
-----------------------------------------------------------------------------+
From: Frank Yellin
Subject: Re: Behaviour of MAPCAR
Date: 
Message-ID: <FY.95Jul17142949@pan.firstperson.com>
In article <··········@camelot.ccs.neu.edu> ·····@ccs.neu.edu (Michael
Tselman) writes: 

> Read page 30 of CLtL2. In particular it says (last paragraph):
> 	"... Most functions advertised to operate on lists expect to be given
> 	true lists. Throughout this book, unless otherwise specified, it is
> 	an error to pass a dotted list to a function that is specified to
> 	require a list as an argument."

And "it is an error" doesn't mean "should report an error".  

The implementation is free to handle "it is an error" any way it wants.

-- Frank Yellin

      
From: Steven D. Majewski
Subject: Re: Behaviour of MAPCAR
Date: 
Message-ID: <DBx9o2.DMD@murdoch.acc.Virginia.EDU>
>Stephan Kepser (······@cis.uni-muenchen.de) wrote:
>: Hi,
>
>: when debugging my program I discovered the following behaviour of MAPCAR  
>: (in Lucid CommonLisp v.4.1.1), which astonished me:
>
>: >(mapcar #'(lambda (x) '*a*) '(a b)
>: (*a* *a*)
>
>: >(mapcar #'(lambda (x) '*a*) '(a . b)
>: (*a*)
>

In article <··········@camelot.ccs.neu.edu>,
Michael Tselman <·····@ccs.neu.edu> wrote:
>
>Read page 30 of CLtL2. In particular it says (last paragraph):
>	"... Most functions advertised to operate on lists expect to be given
>	true lists. Throughout this book, unless otherwise specified, it is
>	an error to pass a dotted list to a function that is specified to
>	require a list as an argument."
>

I missed that note, however, as I noted to Stephan Kepser in email,
that even without that note and assuming it was ambiguous whether 
mapcar should work on dotted lists, his expectation of how it ought
to work is NOT one of the reasonable alternatives:

>: The first operation, the one on true (i.e. non-dotted) lists, works as  
>: expected. But what about the second? Obviously, the function (lambda (x)  
>: '*a*) is only applied to the car of (a . b). Since the cdr is a non-NIL  
>: element, one may (and indeed I did) have expected that the function is  
>: applied to the cdr, too.

The reasonable alternatives are either: 
 (1) That it's an error ( which, if the implemantation  does no other
   checking, will likely happen when trying to take the CAR of 'b ) 
 (2) That the definition says the function is applied to the
 successive CAR's - it doesn't mention the CDRs of the list, although 
 "successive" implies "recursive" which implies what it's recursing 
  on are the successive CDRs. 

In neither interpretation, should one *ever* expect the mapped function
to be applied to the CDR, and the fact that the final CDR is somehow
special doesn't make any difference. 


That paragraph may remove the ambiguity, but Stephan's expectation -
that the function be applied to the cdr - was never an option. 


---|  Steven D. Majewski   (804-982-0831)  <·····@Virginia.EDU>  |---
---|  Computer Systems Engineer          University of Virginia  |---
---|  Department of Molecular Physiology and Biological Physics  |---
---|  Box 449 Health Science Center    Charlottesville,VA 22908  |---
 [ "The grass is always greener, except at t=0" - Stan Kelly-Bootle ]
From: Stephan Kepser
Subject: Re: Behaviour of MAPCAR
Date: 
Message-ID: <3uiok2$1b1@sparcserver.lrz-muenchen.de>
Many thanks to all who responded to my post including those who did so by  
email. I had not expected to provoke such massive response. The case is  
pretty clear: CLtL2 states on page 30 that dotted lists are invalid input  
to normal functions operating on lists. David Margolies says that this  
statement transfers to the new ANSI standard. 

Still, I think, there are two lessons to learn from the responses.

1) Several people claimed that even without the clarification on page 30,  
the result is not surprising. I don't know, if I see this right, but it  
seems to me, that the arguments stem from people who are very long in the  
business of Lisp programming. They have access to a tradition of about 20  
years. This is surely not the case with me. So this is a warning for both  
sides. For beginners, because it means that certain statements are only  
fully understandable with the knowledge of some tradition, and for the  
experienced, because a statement that they think is clear may be so only  
with quite some background knowledge, and they are not aware that they are  
using it. This is particularly a problem when writing a self contained  
description of the language. It must be explicit on everything, can't take  
anything for granted by tradition. I hope this is reflected in the new  
ANSI standard.

2) This is for compiler implementors:
When I set the savety option of the compiler to 3, than I want to see an  
error message, if I call a function with invalid input. This is one of the  
key ideas in deciding for savety, that invalid arguments are detected.  
Only when savety is switched off, the implementor may do what he likes. If  
Lisp stresses on savety over speed (as was claimed in many Lisp vs. C  
discussions), then argument checking is not an option or a matter of  
taste, it's a Must. 
Concerning MAPCAR, Allegro does so, Lucid doesn't.  

--
Stephan Kepser           ······@cis.uni-muenchen.de
CIS   Centrum fuer Informations- und Sprachverarbeitung
LMU Muenchen, Wagmuellerstr. 23/III, D-80538 Muenchen,  Germany
Tel: +49 +89/2110666     Fax: +49 +89/2110674
From: Simon Brooke
Subject: Re: Behaviour of MAPCAR
Date: 
Message-ID: <DBxDu0.7wK@rheged.dircon.co.uk>
In article <··········@sparcserver.lrz-muenchen.de>,
Stephan Kepser <······@cis.uni-muenchen.de> wrote:
>Hi,
>
>when debugging my program I discovered the following behaviour of MAPCAR  
>(in Lucid CommonLisp v.4.1.1), which astonished me:
>
>>(mapcar #'(lambda (x) '*a*) '(a b)
>(*a* *a*)
>
>>(mapcar #'(lambda (x) '*a*) '(a . b)
>(*a*)
>
>The first operation, the one on true (i.e. non-dotted) lists, works as  
>expected. But what about the second? 

It works as expected too.

>When discussing mapping functions (7.8.4, p. 171 ff), CLtL2 only speaks  
>about lists, 

Just so. MAPCAR takes as it's second argument a list: that is, a cons
cell whose CDR is a list. It doesn't take a dotted pair, which is not
a list.

>And what  
>mapcar is suppossed to do with the end of a list, is - in my eyes - open  
>to interpretation. All, that said is
>
>	First the function is applied to the car of each list,
>	then to the cadr of each list, and so on. 
>	                             (CLtL2, p.171)
>
>So "and so on" till what? 

Till the end of the list.

>The explanation seems to imply that mapcar is  
>supposed to work on true lists.

It does.

>How should things work? Could someone please explain.

As they do. LUCID's behaviour is correct, and any other behaviour
would astonish me. There is, after all, no CADR of a dotted pair.


-- 
------- ·····@rheged.dircon.co.uk (Simon Brooke)

	There are no messages. The above is just a random stream of
	bytes. Any opinion or meaning you find in it is your own creation.
From: Jeffrey McArthur
Subject: Re: Behaviour of MAPCAR
Date: 
Message-ID: <3uiecg$s40@news2.delphi.com>
Stephan Kepser wrote:
>>(mapcar #'(lambda (x) '*a*) '(a b)
>(*a* *a*)
>
>>(mapcar #'(lambda (x) '*a*) '(a . b)
>(*a*)

Remember (a b) is actually (a . (b . nil))

So 'a is the CAR of (a b) and 'b is the CADR or (CAR (CDR (a b)).  In the
case of (a . b) 'a is the CAR, and the CDR is 'b.  But the CADR of (a . b)
is nil.  {The CAR of an atom is nil.}

I think I did pretty good for someone who hasn't seriously looked at lisp
is around 10 years.
----
    Jeffrey M\kern-.05em\raise.5ex\hbox{\b c}\kern-.05emArthur
    a.k.a. Jeffrey McArthur          email: ··········@bix.com
    home:  (410) 290-6935

The opinions expressed are mine.  They do not reflect the opinions
of my employer.  My access to the Internet is NOT paid for by my
employer. My access to the Internet is on my own time at my own
expense.
From: Jeffrey McArthur
Subject: Re: Behaviour of MAPCAR
Date: 
Message-ID: <3uk4k8$77o@news2.delphi.com>
Stephan Kepser wrote:
>>(mapcar #'(lambda (x) '*a*) '(a b)
>(*a* *a*)
>
>>(mapcar #'(lambda (x) '*a*) '(a . b)
>(*a*)

Remember (a b) is actually (a . (b . nil))

So 'a is the CAR of (a b) and 'b is the CADR or (CAR (CDR (a b)).  In the
case of (a . b) 'a is the CAR, and the CDR is 'b.  But the CADR of (a . b)
is nil.  {The CAR of an atom is nil.}

I think I did pretty good for someone who hasn't seriously looked at lisp
is around 10 years.
----
    Jeffrey M\kern-.05em\raise.5ex\hbox{\b c}\kern-.05emArthur
    a.k.a. Jeffrey McArthur          email: ··········@bix.com
    home:  (410) 290-6935

The opinions expressed are mine.  They do not reflect the opinions
of my employer.  My access to the Internet is NOT paid for by my
employer. My access to the Internet is on my own time at my own
expense.