[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

UPGRADE-ARRAY-ELEMENT-TYPE: a sloution for the array TYPEP problem?

re: I don't know why the declaration vs discrimination thing was done.  
    . . . 
    Offhand getting rid of this distinction into two kinds of types seems
    like a good idea.  However, I'm a bit leery of changing things in the
    language when I don't understand why they are there.  . . . 

I share your queasiness here.  My first impluse is to ask for a function
(which would be "implementation revealing") named UPGRADE-ARRAY-ELEMENT-TYPE
whose purpose would be to tell you what the canonical representation for a
type name is (when used as an :element-type specifier).   E.g., suppose:

    (setq a (make-array size :element-type 'foo)
    (setq real-element-type (upgrade-array-element-type 'foo))
then the following two specifiers would be type-equivalent:

    `(array foo)     `(array ,real-element-type)

even if "'foo" and "real-element-type" be not type-equivalent.  Furthermore,

    (typep (aref a n) real-element-type)

is always true, even though in the face of non-trivial upgrading,

   (typep (aref a n) 'foo)

could be false.

I would consider UPGRADE-ARRAY-ELEMENT-TYPE in the same genre of features
as MOST-POSITIVE-FIXNUM.   Programmers would inevitably choose to use
"real-element-type" rather than "'foo", and ocasionally find that their
code wasn't so trivially portable to a system that had a fundamentally
different kind of upgrading.

But if "upgrading" is to remain in CL, I don't see how we can avoid
opening it up a bit for inspection.

My second impluse is to toss out upgrading altogether, and require every 
array to remember the type (or, a canonical name therefor) by which it 
was created.  The reason this is second, rather than first, on my list is 
that to make types absolutely portable this way is a very pyrrhic success.
Sure, your program will port to the Y machine -- it will just run two orders
of magnitude slower [because you started out on, say, a Multics machine 
with (MOD 512) arrays optimized, and ported to an implementation for an 
engineering workstation that prefers (UNSIGNED-BYTE 8) arrays ...].

Finally, as I've said before, I don't think it's an acceptable solution 
for Lisp to take the same route as C (and others) to achieve portability.
The kinds of array types in such languages are limited to a small (albeit
very useful) set that seems inspired by one particular hardware architecture.

-- JonL --

P.S. Of course UPGRADE-ARRAY-ELEMENT-TYPE can currently be implemented
     in a "consy" way doing something like:
         (array-element-type (make-array 0 :element-type 'foo))
     But the presence of a "first class" function UPGRADE-ARRAY-ELEMENT-TYPE 
     would be more for the purpose of encouraging cognizance of these
     problems than for avoiding the consing.  Implicitly, such a function
     lies underneath any implementation of MAKE-ARRAY already.