From: David Bakhash
Subject: on initializing arrays...
Date: 
Message-ID: <cxj3earzsfv.fsf@engc.bu.edu>
hey,

I recently got slammed because I was trying to build a huge (2D) array 
of bytes (size-8 bit-vectors).  So each element of the matrix was
itself a bit-array.  So I did something like this:

(make-array '(12 12)
	:initial-element #8*0
	:element-type 'simple-bit-vector)

but that was a disaster, because all the elements of the 2D array were 
sharing the same single bit-vector.  So I did the next obvious thing:

(make-array '(12 12)
	:initial-element (make-array 8
				:initial-element 0
				:element-type 'bit))

but that did precisely the same thing.  What I had to do, in the end
was something like this:

(setq a (make-array '(12 12)
		:element-type '(simple-bit-vector 8)))
(loop for i below (array-total-size a)
      do
	(setf (row-major-aref a i) (make-array 8
					:initial-element 0
					:element-type 'bit)))

or something like that.

So, the question is...when making an array, is there a way to tell
`make-array' to re-evaluate the :initial-element form for each
element?

thanks,
dave

From: Tim Bradshaw
Subject: Re: on initializing arrays...
Date: 
Message-ID: <ey34sv7bspw.fsf@todday.aiai.ed.ac.uk>
* David Bakhash wrote:

> So, the question is...when making an array, is there a way to tell
> `make-array' to re-evaluate the :initial-element form for each
> element?

No, because MAKE-ARRAY is a function so its arguments get evaluated in
the normal way.  It would be possible to imagine a function like
MAKE-ARRAY which *copied* the initial element, but that would require
a general notion of what it means to copy something.

I suppose a better alternative approach would be a slightly mutant
make-array which had an optional INITIAL-ELEMENT-FUNCTION keyword
argument, so you could call:

	(make-array (..) ... 
	 :initial-element-function #'(lambda ()
					(make-array ...)))

Something like that would be quite easy to write.

--tim
From: David D. Smith
Subject: Re: on initializing arrays...
Date: 
Message-ID: <dds-2008981158050001@x068.bit-net.com>
In article <···············@engc.bu.edu>, David Bakhash <·····@bu.edu> wrote:

> hey,
> 
...
> So, the question is...when making an array, is there a way to tell
> `make-array' to re-evaluate the :initial-element form for each
> element?

Use :INITIAL-CONTENTS instead of :INITIAL-ELEMENT.

d
From: Lyman S. Taylor
Subject: Re: on initializing arrays...
Date: 
Message-ID: <6rhmet$jen@pravda.cc.gatech.edu>
In article <····················@x068.bit-net.com>,
David D. Smith <···@flavors.com> wrote:
>In article <···············@engc.bu.edu>, David Bakhash <·····@bu.edu> wrote:
>
>> hey,
>> 
>...
>> So, the question is...when making an array, is there a way to tell
>> `make-array' to re-evaluate the :initial-element form for each
>> element?
>
>Use :INITIAL-CONTENTS instead of :INITIAL-ELEMENT.

   Yeah but constructing the sequence of sequences of bit vectors to pass as 
   the initial contents, is likely to involve as much "work" as the code that 
   initialized each array element.   In addition, you create structures
   that are probably immediately disgarded. 

   As a general Lisp rule of thumb, copies are only generated unless you 
   explicitly ask for them (i.e.,  upon demand).  If you want 144 unique bit 
   vectors you will have to ask for each one.   Otherwise, you have a 
   reference to the same one. 



-- 

Lyman S. Taylor			"Because no matter where you go,
(·····@cc.gatech.edu)			there you are."
						Buckaroo Banzai
From: Kent M Pitman
Subject: Re: on initializing arrays...
Date: 
Message-ID: <sfwu337bh4u.fsf@world.std.com>
·····@cc.gatech.edu (Lyman S. Taylor) writes:

>    As a general Lisp rule of thumb, copies are only generated unless you 
>    explicitly ask for them (i.e.,  upon demand). 

Indeed.  And this is not just Lisp doing the wrong thing.  Object
identity matters in Lisp, and copying creates a new identity.  There
could be many applications where sharing is important, either for
compactness of storage or because the sharing is used for
communication purposes (someone is going to side-effect one element
and expect to see that side-effect in another).  Lisp can't guess that
you want copying since either copying or not-copying is appropriate to
any given application.  And then there's the whole issue of what it
MEANS to copy something ... asked and answered recently enough on this
list that I'm not going to revisit THAT!  

My analogy web brings up a rule I used to hear at Symbolics about
abbreviating function and variable names: don't do it.  There are many
ways to abbreviate something but only one way not to.  So it's easier
to remember the word spelled out than abbreviated; let people use
completion tools if they have trouble typing it.  This issue seems the
same to me.  Not copying is just plain safer than copying.  There is
only one way to not copy something, and there are many ways to copy
something (all but one of which are usually wrong in any given case).

If there's a fault here, it's the lack of a :INITIAL-ELEMENT-FUNCTION,
but by the time you get through the added syntax for that, I'm not
sure it's a lot different than the loop that does the initialization.
And an :INITIAL-ELEMENT-FUNCTION wouldn't address other issues, like 
leaving some elements uninitialized or making it easy to accumulate
values from previous elements to put in later elements.  Loops are
more general.
From: Barry Margolin
Subject: Re: on initializing arrays...
Date: 
Message-ID: <iP_C1.21$DY4.233592@burlma1-snr1.gtei.net>
In article <···············@world.std.com>,
Kent M Pitman  <······@world.std.com> wrote:
>Indeed.  And this is not just Lisp doing the wrong thing.  Object
>identity matters in Lisp, and copying creates a new identity.  There
>could be many applications where sharing is important, either for
>compactness of storage or because the sharing is used for
>communication purposes (someone is going to side-effect one element
>and expect to see that side-effect in another).  Lisp can't guess that
>you want copying since either copying or not-copying is appropriate to
>any given application.  And then there's the whole issue of what it
>MEANS to copy something ... asked and answered recently enough on this
>list that I'm not going to revisit THAT!  

Of course, the opposite philosophy is also valid.  Many languages copy
everything all the time, and when you don't want copies you must use
explicit pointers or references.

Neither is right or wrong, they're just different approaches that are often
appropriate for different types of applications.  Lisp was designed to make
it easier to deal with complex data relationships, where object identity
often matters, so it handles references implicitly and never automatically
copies.  Other languages have been designed for applications dealing with
scalar and tabular data, where often just the numeric and character values
are important, so copying is implict and the programmer must deal with
pointers manually.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
From: David Thornley
Subject: Re: on initializing arrays...
Date: 
Message-ID: <IW0D1.1242$813.4297483@ptah.visi.com>
In article <···············@world.std.com>,
Kent M Pitman  <······@world.std.com> wrote:
>·····@cc.gatech.edu (Lyman S. Taylor) writes:
>
>>    As a general Lisp rule of thumb, copies are only generated unless you 
>>    explicitly ask for them (i.e.,  upon demand). 
>
>Indeed.  And this is not just Lisp doing the wrong thing.  Object
>identity matters in Lisp, and copying creates a new identity.  There

Yup.  Nor is it obvious how deep a copy needs to be.

When I had this problem, I wrote myself a (defgeneric copy...
and defmethods to match.  I was thinking of making the copy
valid for a large number of data objects, but I couldn't think
of any reasonable semantics for copying a symbol, so I didn't.

I ran into a nasty problem with copy depth, since I had forgotten
a certain change to certain objects, and was thinking of them
as immutable when they weren't.

I wouldn't object to some sort of deep copy function in Lisp that
would copy everything down to symbols (sort of an extension of
copy-tree) but I'm not sure how useful that would be.  It would
be nice for getting something going, but I think it would usually
be replaced with something more efficient for production code.



--
David H. Thornley                        | These opinions are mine.  I
·····@thornley.net                       | do give them freely to those
http://www.thornley.net/~thornley/david/ | who run too slowly.       O-
From: Barry Margolin
Subject: Re: on initializing arrays...
Date: 
Message-ID: <WYXC1.8$DY4.233592@burlma1-snr1.gtei.net>
In article <····················@x068.bit-net.com>,
David D. Smith <···@flavors.com> wrote:
>In article <···············@engc.bu.edu>, David Bakhash <·····@bu.edu> wrote:
>> So, the question is...when making an array, is there a way to tell
>> `make-array' to re-evaluate the :initial-element form for each
>> element?
>
>Use :INITIAL-CONTENTS instead of :INITIAL-ELEMENT.

That just changes the problem to how to fill in the list being used as the
initial contents, but doesn't really solve it.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.