Henry G. Baker
Wed, 14 May 1997 07:26:00 -0700 (PDT)
> Another approach is to when you allocate them pass a generator.
> (make-array 10 :allocation immutable :generator '(lambda (i) (random 100)))
> to allocate an immutable array with 10 random numbers in it.
> (make-array (length foo) :allocation immutable :generator
> `(lambda (i) (nth i ,foo)))
> to initialize from a list.
> A simple, clean solution?
This is an excellent idea, for those arrays that can be initialized
with a generator.
How do you actually implement 'make-array' ? (This _is_ a reflective
system, isn't it?) Presumably, you have to allocate a piece of
storage, and then iterate through the array, calling the generator for
each element. Due to the possibility of side-effects, you have to
define the order -- e.g., 1st to last -- but even more importantly,
what does the array look like to the GC, since a GC can happen within
one of the calls to the generator?
This is why I lean towards the 'linear' solution: allocate a 'linear'
piece of storage and fill it in as before. Since it is 'linear'
(refcount==1), no one else can even see that it exists. Since it has
only one pointer, there is no possibility of a 'dangling pointer' when
it is converted (frozen) from a mutable linear type into a functional
type. If one of the generator calls craps out with an exception, the
usual 'unwind-protect' sort of behavior built into every linear type
kicks in to make sure that the linear object is freed.
www/ftp directory URL: