From: Patrick Wray
Subject: Unimportant question - Just curious
Date: 
Message-ID: <7dibi0$a41$1@reader1.reader.news.ozemail.net>
Snippet from a script:

> (setf people '(patrick paul michael peter))
(patrick paul michael peter)
> (remove (first people) people)
(paul michael peter)
> ;; This one had me puzzled for a while...
(remove (last people) people)
(patrick paul michael peter)
> ;; Until I realised that "last" returns a list
(remove (first (last people)) people)
(patrick paul michael)
>

It doesn't matter in the least, but I'm just curious: Why does "first"
return an atom whereas "last" returns a list?

From: Wolfgang Hukriede
Subject: Re: Unimportant question - Just curious
Date: 
Message-ID: <7dik5h$q96$1@bossix.informatik.uni-kiel.de>
> It doesn't matter in the least, but I'm just curious: Why does "first"
> return an atom whereas "last" returns a list?

So that you can rplacd to it. 

Hth, W.
From: Kent M Pitman
Subject: Re: Unimportant question - Just curious
Date: 
Message-ID: <sfwpv5vqa6e.fsf@world.std.com>
Wolfgang Hukriede <·········@ifm.uni-kiel.de> writes:

> > It doesn't matter in the least, but I'm just curious: Why does "first"
> > return an atom whereas "last" returns a list?
> 
> So that you can rplacd to it. 

This is right.  But, FWIW, it was annoyance with this same irritating
little problem that led me to propose that NTH take an "n" second
argument.

It doesn't wholly fix the problem because it begs the question of why
FIRST doesn't do the same thing, but there is already a kind of
asymmetry between "car" and "cdr" with respect to lists, so the fact
that there is a similar skew between first and last I guess should
feel "natural".  Think of it like car/cdr where the cdr is the last
instead of the first cdr.  Anyway, now at least if you say (LAST '(A B
C) 2) you get back a 2-list, and while I didn't think there was huge
call for that, it at least was intended to help explain why (LAST '(A
B C)) should return a 1-list.

Having LAST take this argument also make it symmetric with BUTLAST.

But like the emacs command set, if you push the regularities too far,
you run into an irregularity again, and you ultimately try to confine
yourself to clusters of things that make sense together and be happy
with that.  It's a language that arose as a conglomeration of other
languages and had as its very definition that it didn't come from a 
single unified idea, so it does have its practical limits of consistency.
It trades consistency sometimes for practicality...

Hopefully it's at least some comfort to know the designers spent at
least *some* time feeling guilt over the fact that others are kept up
late worrying about these things...

This was issue LAST-N in the X3J13 cleanup issues.  It's in CLHS.
From: Vassil Nikolov
Subject: Re: Unimportant question - Just curious
Date: 
Message-ID: <7djkvo$ls1$1@nnrp1.dejanews.com>
In article <···············@world.std.com>,
  Kent M Pitman <······@world.std.com> wrote:
> Wolfgang Hukriede <·········@ifm.uni-kiel.de> writes:
>
> > > It doesn't matter in the least, but I'm just curious: Why does "first"
> > > return an atom whereas "last" returns a list?
> >
> > So that you can rplacd to it.
>
> This is right.  But, FWIW, it was annoyance with this same irritating
> little problem that led me to propose that NTH take an "n" second
> argument.

Isn't it LAST here rather than NTH?

> It doesn't wholly fix the problem because it begs the question of why
> FIRST doesn't do the same thing
(...)

I had never seen things this way before;  for one,

  (first '(a b c)) => (a)

means FIRST conses a fresh cell, and is not the same as CAR; and two,
one can easily get the last element by doing FIRST of LAST, while
the opposite is not so easy.

Note that besides doing SETF of REST of LAST, one may need the
reference to the last cons e.g. to build some sort of shared
structure.

By way of analogies, SUBSEQ, LAST, and BUTLAST provide a more complete
set than head(1) and tail(1) (unless head(1) has recently been extended
to count from the end as well, and I haven't noticed; sorry, don't
have a unix session at hand right now).

Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Kent M Pitman
Subject: Re: Unimportant question - Just curious
Date: 
Message-ID: <sfw4sn6ckji.fsf@world.std.com>
Vassil Nikolov <········@poboxes.com> writes:

> Isn't it LAST here rather than NTH?

Heh.  Yeah.
From: David Bakhash
Subject: Re: Unimportant question - Just curious
Date: 
Message-ID: <cxjemmax5h3.fsf@engc.bu.edu>
I have found times in code where it was certainly useful to have
first-n and an nfirst-n functions.  I just made them.  They're really
easy to enough to write.

dave
From: Vassil Nikolov
Subject: Re: Unimportant question - Just curious
Date: 
Message-ID: <7djo34$oba$1@nnrp1.dejanews.com>
In article <···············@engc.bu.edu>,
  David Bakhash <·····@bu.edu> wrote:
> I have found times in code where it was certainly useful to have
> first-n and an nfirst-n functions.  I just made them.  They're really
> easy to enough to write.

;;; not for homeworks
;;; no error checking (adding assertions is I hope obvious)
;;; declare L a list and N a non-negative integer if necessary

(defun first-n (l n) (subseq l 0 n))

(defun nfirst-n (l n) (setf (nthcdr l n) '()))

Easy indeed.

Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own