From: Jack Unrue
Subject: adjust-array vs. :adjustable t
Date: 
Message-ID: <vsinf25eoj0qkdmirkedgumvtem37hugnj@4ax.com>
I'm afraid this topic has been raised in years past, but
I'm not 100% comfortable with the info I've dug up so far
and want to be sure I'm not missing anything.

If I want to copy an array, being interested only in the
original array dimension and elements, but ensure that the
result is adjustable and has a fill pointer, I believe I'm
forced to call MAKE-ARRAY and manually copy elements of the
source to the new array. The point is to do a defensive
copy, so I don't think I want a displaced array. And yes,
this is a shallow copy that I'm talking about.

Neither COPY-SEQ nor SUBSEQ are specified to preserve
either :adjustable or :fill-pointer attributes. The
ADJUST-ARRAY function allows me to set the fill pointer
for the copy (note that I'm not wanting to fiddle with the
original), but it is not specified to let me change
the :adjustable attribute.

If it were possible to change the :adjustable attribute,
doing so might require re-allocation of the array, maybe
because the layout of the hidden store would be different.

Is my understanding correct?

What has me slightly confused is that if an array is created
*without* :adjustable t, then ADJUST-ARRAY may in fact return
a different array. So if it's OK to reallocate an array in one
circumstance, why not allow it in the other?

-- 
Jack Unrue

From: Barry Margolin
Subject: Re: adjust-array vs. :adjustable t
Date: 
Message-ID: <barmar-1E1CBD.09562404092006@comcast.dca.giganews.com>
In article <··································@4ax.com>,
 Jack Unrue <·······@example.tld> wrote:

> I'm afraid this topic has been raised in years past, but
> I'm not 100% comfortable with the info I've dug up so far
> and want to be sure I'm not missing anything.
> 
> If I want to copy an array, being interested only in the
> original array dimension and elements, but ensure that the
> result is adjustable and has a fill pointer, I believe I'm
> forced to call MAKE-ARRAY and manually copy elements of the
> source to the new array. The point is to do a defensive
> copy, so I don't think I want a displaced array. And yes,
> this is a shallow copy that I'm talking about.
> 
> Neither COPY-SEQ nor SUBSEQ are specified to preserve
> either :adjustable or :fill-pointer attributes. The
> ADJUST-ARRAY function allows me to set the fill pointer
> for the copy (note that I'm not wanting to fiddle with the
> original), but it is not specified to let me change
> the :adjustable attribute.
> 
> If it were possible to change the :adjustable attribute,
> doing so might require re-allocation of the array, maybe
> because the layout of the hidden store would be different.
> 
> Is my understanding correct?

Yes.  An adjustable array is likely to be implemented with indirection 
from the dope vector to the contents, while a non-adjustable one can 
have them together.

> What has me slightly confused is that if an array is created
> *without* :adjustable t, then ADJUST-ARRAY may in fact return
> a different array. So if it's OK to reallocate an array in one
> circumstance, why not allow it in the other?

Because the ability to call it on non-adjustable arrays was a late 
addition to the language, and we didn't think of adding additional 
attributes that can be changed as a consequence.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Jack Unrue
Subject: Re: adjust-array vs. :adjustable t
Date: 
Message-ID: <8bhof2ti62lf3dlg2lpvqus5tig5diratp@4ax.com>
On Mon, 04 Sep 2006 09:56:24 -0400, Barry Margolin <······@alum.mit.edu> wrote:
>
> In article <··································@4ax.com>,
>  Jack Unrue <·······@example.tld> wrote:
> > 
> > Is my understanding correct?
> 
> Yes.  An adjustable array is likely to be implemented with indirection 
> from the dope vector to the contents, while a non-adjustable one can 
> have them together.
> 
> > What has me slightly confused is that if an array is created
> > *without* :adjustable t, then ADJUST-ARRAY may in fact return
> > a different array. So if it's OK to reallocate an array in one
> > circumstance, why not allow it in the other?
> 
> Because the ability to call it on non-adjustable arrays was a late 
> addition to the language, and we didn't think of adding additional 
> attributes that can be changed as a consequence.

Thanks Barry!

-- 
Jack Unrue
From: Ivan Boldyrev
Subject: Re: adjust-array vs. :adjustable t
Date: 
Message-ID: <2ml0t3-oei.ln1@ibhome.cgitftp.uiggm.nsc.ru>
On 9587 day of my life Jack Unrue wrote:
> If I want to copy an array, being interested only in the
> original array dimension and elements, but ensure that the
> result is adjustable and has a fill pointer, I believe I'm
> forced to call MAKE-ARRAY and manually copy elements of the
> source to the new array.

(make-array (array-dimensions original-array)
            :initial-contents original-array
            :fill-pointer t
            :adjustable t)

-- 
Ivan Boldyrev

                                                  Is 'morning' a gerund?
From: Pascal Bourguignon
Subject: Re: adjust-array vs. :adjustable t
Date: 
Message-ID: <877j0i7zlw.fsf@thalassa.informatimago.com>
Ivan Boldyrev <···············@cgitftp.uiggm.nsc.ru> writes:

> On 9587 day of my life Jack Unrue wrote:
>> If I want to copy an array, being interested only in the
>> original array dimension and elements, but ensure that the
>> result is adjustable and has a fill pointer, I believe I'm
>> forced to call MAKE-ARRAY and manually copy elements of the
>> source to the new array.
>
> (make-array (array-dimensions original-array)
>             :initial-contents original-array
>             :fill-pointer t
>             :adjustable t)

Initial contents must be a list of lists.

(defun array-to-list (array)
  (if (= 1 (length (array-dimensions array)))
      (coerce array 'list)
      (loop
         :for i :from 0 :below (array-dimension array 0)
         :for subarray = (make-array (rest (array-dimensions array))
                                     :element-type (array-element-type array)
                                     :displaced-to array
                                     :displaced-index-offset
                                     (apply (function *) i
                                            (rest (array-dimensions array))))
         :collect (array-to-list subarray))))


 (make-array (array-dimensions original-array)
             :initial-contents (array-to-list original-array)
             :fill-pointer t
             :adjustable t)

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

THIS IS A 100% MATTER PRODUCT: In the unlikely event that this
merchandise should contact antimatter in any form, a catastrophic
explosion will result.
From: Rob Warnock
Subject: Re: adjust-array vs. :adjustable t
Date: 
Message-ID: <hJOdnVj7ztjmEGPZnZ2dnUVZ_tSdnZ2d@speakeasy.net>
Pascal Bourguignon  <···@informatimago.com> wrote:
+---------------
| Ivan Boldyrev <···············@cgitftp.uiggm.nsc.ru> writes:
| > (make-array (array-dimensions original-array)
| >             :initial-contents original-array
| >             :fill-pointer t
| >             :adjustable t)
| 
| Initial contents must be a list of lists.
+---------------

Uh, no, initial contents must be "a nested structure of sequences"
[CLHS Function MAKE-ARRAY]. His code works just fine on vectors
(well, he forgot to copy the element type):

    > (deflex original-array "hello there, world!!")

    ORIGINAL-ARRAY
    > (make-array (array-dimensions original-array)
		:initial-contents original-array
		:element-type (array-element-type original-array)
		:fill-pointer t
		:adjustable t)

    "hello there, world!!"
    cmu> (describe *)

    "hello there, world!" is a vector of length 20.
    It has a fill pointer, currently 20
    Its element type is specialized to BASE-CHAR.
    >

And for multi-dimensional arrays [rank >1], one can use the double
:DISPLACED-TO trick that Barry Margolin posted week before last,
tweaked so the final array is adjustable:

    ;;; caveat: only lightly tested
    (let* ((tmp-vector1
	    (make-array (array-total-size original-array)
			:element-type (array-element-type original-array)
			:displaced-to original-array))
	   (tmp-vector2
	    (make-array (array-total-size original-array)
			:element-type (array-element-type original-array)
			:adjustable t
			:initial-contents tmp-vector1)))
      (make-array (array-dimensions original-array)
		  :element-type (array-element-type original-array)
		  :adjustable t
		  :displaced-to tmp-vector2))

In neither case is an explicit copy needed, nor conversion of the
contents to lists.


-Rob

p.s. We should also remind OP that only vectors can have fill pointers...

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Jack Unrue
Subject: Re: adjust-array vs. :adjustable t
Date: 
Message-ID: <skptf29kge3od054d52bftaq8hsqgb12oa@4ax.com>
On Wed, 06 Sep 2006 03:57:31 -0500, ····@rpw3.org (Rob Warnock) wrote:
> 
> p.s. We should also remind OP that only vectors can have fill pointers...

I had in fact read the CLHS on this topic very thoroughly before posting
the original question -- nevertheless it's good to have this discussion.
And thanks for the reminder :-)

-- 
Jack Unrue