On Sun, Feb 23, 2003 at 09:19:37AM -0500, rif wrote:
> Over the last week, I've been optimizing a large-scale numerical
> program in CMUCL.  One of the key lessons is that arrays of
> double-floats are much faster to work with than arrays whose
> array-element-type is T.  Not too surprising.
> 
> Suppose I create a structure foo, whose elements are a fixnum and a
> double-float.  Is there any way in CMUCL to create an array whose
> array-element-type is foo?  If not, why not (just curious about the
> design concerns)?  So far, all my attempts give me a "generic"
> (simple-array T).

(I had the same culture shock, coming from C/C++. FWIW, it's probably
less shocking if you come from Java.)

It's not a CMU CL issue. In CL as in Java, this behavior follows from
the spec, because of the Liskov substitutability mentioned below and
even more directly because the same structure instance can easily be
"in" more than one array, and you can portably tell it's the same
instance by EQL or the usual "if you cut this instance, doth not that
instance bleed" argument:
  (defstruct foo x y)
  (let ((a1 (make-array 10))
        (a2 (make-array 14)))
    (setf (aref a1 0)
          (setf (aref a2 0)
                (make-foo :x 10 :y 3.1622777)))
    (setf (foo-x (aref a1 0))
          -3.1622777)
    (foo-x (aref a2 0)))
  => -3.1622777
So it's not just an efficiency issue in the CMU CL implementation, but
part of the specified behavior of the language.

One reason is that garbage collectors are simpler when individually
collectable objects are never physically embedded inside other
collectable objects, but only referred to by pointers embedded inside
other collectable objects.

Another reason is that Lispers tend to think of dynamically allocated
compound objects as an ordinary case, not just something for very
special occasions. Historically (when these design decisions were
originally being made, I think) that meant things like arrays "of"
lists; and arrays "of" lists have more natural behavior when you
implement them as arrays of references to CONSes than when you
implement them as arrays of CONSes in the C/C++ sense. These days, now
that most people are comfortable working with inheritance, you might
be more convinced by the Liskov (?) substitution principle on arrays
"of" instances of classes. We'd like to be able to use an instance of
a subclass of FOO as an element in an array which is declared to have
elements of type FOO, and it's hard to achieve that without this layer
of indirection.

-- 
William Harold Newman <[EMAIL PROTECTED]>
Remember: don't show fear.  Testers can sense fear.
  -- Paul F. Dietz, cmucl-imp 2003-01-27
PGP key fingerprint 85 CE 1C BA 79 8D 51 8C  B9 25 FB EE E0 C3 E5 7C

Reply via email to