From: Paul Dietz
Subject: Question about DYNAMIC-EXTENT
Date: 
Message-ID: <876udj$5gr$1@schbbs.mot.com>
I was wondering if the following is legal
Lisp:

   (let* ((hd (cons nil nil))
	  (tl hd))
	(declare (dynamic-extent hd))
	(dotimes (i 100)
	  (setq tl (setf (cdr tl) (cons i nil))))
	(cdr hd))

The question is: does the DYNAMIC-EXTENT declaration
apply to just the first cons cell, or to the whole
list?  If the latter, this code is wrong.

	Paul Dietz
	······@email.mot.com

From: Barry Margolin
Subject: Re: Question about DYNAMIC-EXTENT
Date: 
Message-ID: <KoDl4.14$xI3.270@burlma1-snr2>
In article <············@schbbs.mot.com>,
Paul Dietz <·····@comm.mot.com> wrote:
>I was wondering if the following is legal
>Lisp:
>
>   (let* ((hd (cons nil nil))
>	  (tl hd))
>	(declare (dynamic-extent hd))
>	(dotimes (i 100)
>	  (setq tl (setf (cdr tl) (cons i nil))))
>	(cdr hd))
>
>The question is: does the DYNAMIC-EXTENT declaration
>apply to just the first cons cell, or to the whole
>list?  If the latter, this code is wrong.

It applies to everything that's reachable from the cons cell at any time
during the execution of that LET's body.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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: Paul Dietz
Subject: Re: Question about DYNAMIC-EXTENT
Date: 
Message-ID: <87710a$6f4$1@schbbs.mot.com>
In article <················@burlma1-snr2>,
Barry Margolin  <······@bbnplanet.com> wrote:

>>The question is: does the DYNAMIC-EXTENT declaration
>>apply to just the first cons cell, or to the whole
>>list?  If the latter, this code is wrong.
>
> It applies to everything that's reachable from the cons cell at any time
> during the execution of that LET's body.

This doesn't seem right.  The standard says it should
apply to objects that are reachable from the cons cell
*and otherwise inaccessible at any time the value
of hd changes.*  That second condition is what has me
confused here.

	Paul Dietz
	······@email.mot.com
From: Barry Margolin
Subject: Re: Question about DYNAMIC-EXTENT
Date: 
Message-ID: <fUEl4.24$xI3.365@burlma1-snr2>
In article <············@schbbs.mot.com>,
Paul Dietz <·····@comm.mot.com> wrote:
>In article <················@burlma1-snr2>,
>Barry Margolin  <······@bbnplanet.com> wrote:
>
>>>The question is: does the DYNAMIC-EXTENT declaration
>>>apply to just the first cons cell, or to the whole
>>>list?  If the latter, this code is wrong.
>>
>> It applies to everything that's reachable from the cons cell at any time
>> during the execution of that LET's body.
>
>This doesn't seem right.  The standard says it should
>apply to objects that are reachable from the cons cell
>*and otherwise inaccessible at any time the value
>of hd changes.*  That second condition is what has me
>confused here.

Good point.  I should have said "everything that's *only* reachable from
the cons cell at any time during the execution of that LET's body."  That's
the one-sentence summary of the complex description of DYNAMIC-EXTENT.

So if you have something like:

(let ((dyn-var (cons nil nil))
      non-dyn-var))
  (declare (dynamic-extent dyn-var))
  (setq non-dyn-var (cons nil nil))
  (setf (car dyn-var) (cons 'a 'b)
        (cdr dyn-var) non-dyn-var)
  <some-form>)

It would be OK for <some-form> to be (cdr dyn-var), because that cons is
also accessible via non-dyn-var, but not for it to be (car dyn-var),
because that cons cell was never stored in any accessible place.  It can
also be (caar dyn-var), because that returns the symbol A, which is
interned in a package, so it's accessible that way.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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: Paul Dietz
Subject: Re: Question about DYNAMIC-EXTENT
Date: 
Message-ID: <877dhe$at9$1@schbbs.mot.com>
In article <················@burlma1-snr2>,
Barry Margolin  <······@bbnplanet.com> wrote:

> Good point.  I should have said "everything that's *only* reachable from
> the cons cell at any time during the execution of that LET's body."  That's
> the one-sentence summary of the complex description of DYNAMIC-EXTENT.

Even this doesn't seem accurate.  The actual quote from the standard
is:

  In some containing form, F, this declaration asserts for each vari
  (which need not be bound by F), and for each value vij that vari takes
  on, and for each object xijk that is an otherwise inaccessible part of
  vij at any time when vij becomes the value of vari, that just after
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  the execution of F terminates, xijk is either inaccessible (if F
  established a binding for vari) or still an otherwise inaccessible
  part of the current value of vari (if F did not establish a binding
  for vari).

In this case, a dynamic extent var is bound to a single cons cell.
I assume that the value in question, then, is this single cons
cell.  The underlined part of the standard indicates that *only*
that cons cell could be stack allocated.  Other cons cells that
later become reachable from that first cons cell cannot be, even
if they (at that time) are otherwise inaccessible, because the
value of the dynamic var is not changing (in the examples we've
discussed.)

This line of questioning is being driven by a bug we've found
in some of our code that goes away when dynamic-extent declarations
are removed.  I'm trying to determine if its due to a misunderstanding
of the language, or a bug in the lisp compiler we're using.

	Paul Dietz
	······@email.mot.com
From: Barry Margolin
Subject: Re: Question about DYNAMIC-EXTENT
Date: 
Message-ID: <bxHl4.31$xI3.556@burlma1-snr2>
In article <············@schbbs.mot.com>,
Paul Dietz <·····@comm.mot.com> wrote:
>In article <················@burlma1-snr2>,
>Barry Margolin  <······@bbnplanet.com> wrote:
>
>> Good point.  I should have said "everything that's *only* reachable from
>> the cons cell at any time during the execution of that LET's body."  That's
>> the one-sentence summary of the complex description of DYNAMIC-EXTENT.
>
>Even this doesn't seem accurate.  The actual quote from the standard
>is:
>
>  In some containing form, F, this declaration asserts for each vari
>  (which need not be bound by F), and for each value vij that vari takes
>  on, and for each object xijk that is an otherwise inaccessible part of
>  vij at any time when vij becomes the value of vari, that just after
>      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>  the execution of F terminates, xijk is either inaccessible (if F
>  established a binding for vari) or still an otherwise inaccessible
>  part of the current value of vari (if F did not establish a binding
>  for vari).
>
>In this case, a dynamic extent var is bound to a single cons cell.
>I assume that the value in question, then, is this single cons
>cell.  The underlined part of the standard indicates that *only*
>that cons cell could be stack allocated.  Other cons cells that
>later become reachable from that first cons cell cannot be, even
>if they (at that time) are otherwise inaccessible, because the
>value of the dynamic var is not changing (in the examples we've
>discussed.)

I guess this hinges on how "when vij becomes the value of vari" is being
interpreted.  If it only means "at the moment when vari's value first
changes to vij", then you're right.  But if it means "when vari's value is
vij" then it's more extensive.  I interpreted it in the latter way in my
previous message.

Here's the only example of a DYNAMIC-EXTENT object being modified that I
could find in the cleanup proposal that added this declaration:

  (DEFUN ZAP (N M)
    ;; Computes (RANDOM (+ M 1)) at relative speed of roughly O(N).
    ;; It may be slow, but with a good compiler at least it
    ;; doesn't waste much heap storage.  :-)
    (LET ((A (MAKE-ARRAY N)))
      (DECLARE (DYNAMIC-EXTENT A))
      (DOTIMES (I N) 
        (DECLARE (DYNAMIC-EXTENT I))
        (SETF (AREF A I) (RANDOM (+ I 1))))
      (AREF A M)))

This appears to support the first interpretation, because the value of
(AREF A M) was an otherwise inaccessible part when it was assigned to that
array element, but not when the array was assigned to A.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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.