From: David Bakhash
Subject: ACL lacks (setf nthcdr) method
Date: 
Message-ID: <cxjzpaqx83p.fsf@engc.bu.edu>
hey,

I'm trying to figure out why ACL doesn't define a SETF method for
NTHCDR.  I tried doing:

(setf (nthcdr 5 my-list) blah)

and it failed.  The people at franz told me to do, instead:

(setf (cdr (nthcdr 4 my-list) blah))

and said that this was more portable CL.  I don't understand why

(setf nthcdr) is not portable.  Is it the case that the CL spec
specifies what SETF methods must exist?

thanks,
dave

From: Rainer Joswig
Subject: Re: ACL lacks (setf nthcdr) method
Date: 
Message-ID: <joswig-2110981722370001@pbg3.lavielle.com>
In article <···············@engc.bu.edu>, David Bakhash <·····@bu.edu> wrote:

> hey,
> 
> I'm trying to figure out why ACL doesn't define a SETF method for
> NTHCDR.  I tried doing:
> 
> (setf (nthcdr 5 my-list) blah)
> 
> and it failed.  The people at franz told me to do, instead:
> 
> (setf (cdr (nthcdr 4 my-list) blah))
> 
> and said that this was more portable CL.  I don't understand why
> 
> (setf nthcdr) is not portable.  Is it the case that the CL spec
> specifies what SETF methods must exist?

See: ANSI CL HyperSpec: 5.1.2.2 Function Call Forms as Places

-- 
http://www.lavielle.com/~joswig
From: Barry Margolin
Subject: Re: ACL lacks (setf nthcdr) method
Date: 
Message-ID: <EAnX1.118$Sg6.782611@burlma1-snr1.gtei.net>
In article <···············@engc.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
>and said that this was more portable CL.  I don't understand why
>(setf nthcdr) is not portable.  Is it the case that the CL spec
>specifies what SETF methods must exist?

I can't for the life of me remember why we didn't make this a standard
SETFable place.  Maybe Kent does.  It could be we simply didn't think of
it, but I vaguely remember it coming up.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
From: David Bakhash
Subject: Re: ACL lacks (setf nthcdr) method
Date: 
Message-ID: <cxju30xjua0.fsf@engc.bu.edu>
Barry Margolin <······@bbnplanet.com> writes:

> In article <···············@engc.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
> >and said that this was more portable CL.  I don't understand why
> >(setf nthcdr) is not portable.  Is it the case that the CL spec
> >specifies what SETF methods must exist?
> 
> I can't for the life of me remember why we didn't make this a standard
> SETFable place.  Maybe Kent does.  It could be we simply didn't think of
> it, but I vaguely remember it coming up.

someone at Franz said it's because of the non-sensical issue of

(nthcar 0 lst)

which (as we know) returns the list.  Here's part of our email
conversation...

   From: David Bakhash <·····@bu.edu>

   > (defun nbutlastx (list &optional (n 1))
   >   (setf (nthcdr (max 0 (- (length list) n)) list) nil)
   >   list)
   > 
   > Clearly this fails if n equals the length of the list.
   
   all these examples are wrong in that they assume that (setf nthcdr)
   doesn't check for the first arg to nthcdr being 0.  now, *THAT* would
   be nonsensical.  Here's what I mean:

   (defun set-nthcdr-internal (n list x)
     (if (<= n 0) x (setf (cdr (nthcdr (1- n) list) x)) list))

   and then work this in with defsetf for NTHCDR
   
If you mean that you might specify this as the update-fn in the simple
form of defsetf, clearly that won't work and cannot work for the 0
case:

 <8> (compile
      (defun set-nthcdr-internal (n list x)
	(if (<= n 0)
	    x
	  (setf (cdr (nthcdr (1- n) list)) x))
	list))
 set-nthcdr-internal
 nil
 nil
 <9> (defsetf nthcdr set-nthcdr-internal)
 Error: Attempt to make a defsetf definition for the name nthcdr.  This name ...
 [1c] <10> :cont
 nthcdr
 <11> (setf (nthcdr 2 (setq l (list 1 2 3 4 5))) 'z)
 (1 2 . z)
 <12> (setf (nthcdr 0 (setq l (list 1 2 3 4 5))) 'z)
 (1 2 3 4 5)
 <13> l
 (1 2 3 4 5)

The difficulty is that in the 0 case setf the list argument subform to
nthcdr _must_ be a "place acceptable to setf" and that place subform
must be accessible to the setf expander if setf is to be able to
modify it.

I think something like this implements a setfable alternative to
nthcdr, but I'd want to think a lot more about the semantic
constraints on the setf expansion before I would publish such a think
-- especially regarding the consistent treatment and ordered execution
of the argument subforms such as in this nonsense form

   (setf (nthcdr1 (random (incf foo))
		  (cadr (aref my-list-repository
			      (if (>= (incf hour) 24)
				  (setf hour 0)
				hour))))
     (make-list foo))

I've checked the full macroexpansion and it seems to be correct, but
you see how subtle and counterintuitive these things can be.

==================== nthcdr1.cl
(in-package :user)

(defun nthcdr1 (n list) (nthcdr n list))

(define-compiler-macro nthcdr1 (n list) `(nthcdr ,n ,list))

(define-setf-expander nthcdr1 (n list)
  (multiple-value-bind (vars vals stores writer reader)
      (get-setf-expansion list)
    (let ((nn (gensym)))
      (values (list* nn vars)
	      (list* n vals)
	      stores
	      `(if (eql ,nn 0)
		   ,writer
		 (setf (cdr (nthcdr (1- ,nn) ,reader)) ,(car stores)))
	      `(nthcdr ,nn ,reader)))))
==================== END

It's also worth considering what happens if the list subform is a
place that hacks multiple values.  The expansion might cause unused
variable warnings, etc. etc.  It's a lot to think about....
From: ··········@my-dejanews.com
Subject: Re: ACL lacks (setf nthcdr) method
Date: 
Message-ID: <70nmko$4kh$1@nnrp1.dejanews.com>
In article <····················@burlma1-snr1.gtei.net>,
  Barry Margolin <······@bbnplanet.com> wrote:
>
> I can't for the life of me remember why we didn't make this a standard
> SETFable place.  Maybe Kent does.  It could be we simply didn't think of
> it, but I vaguely remember it coming up.
>

I think that the issue was in handling what to do when the index is
greater than the length of the source list:

  (setq x '(a b c))
  (setf (nthcdr 5 x) '(x y z))

Too bad it wasn't decided to be an error...

-- Dan Corkill

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum