Re: More nits to pick with arrays ...

Guido.van.Rossum@cwi.nl
Fri, 05 Nov 1993 10:51:37 +0100

> Note that:
> type(array('f')) == type(array('l')) == <type 'array'>

This merely means that the objects share most of the C code
implementing them...

> >>> from array import array
> >>> f = array( 'f', range( 1, 10 ))
> >>> l = array( 'l', range( 1, 10 ))
> >>> h = array( 'h', range( 1, 10 ))
> >>> h
> array('h', [1, 2, 3, 4, 5, 6, 7, 8, 9])
> >>> h[:3]
> array('h', [1, 2, 3])
> >>> h[-3:]
> array('h', [7, 8, 9])
> >>> h[:3] + h[-3:] #1
> array('h', [1, 2, 3, 1, 2, 3]) #2
> >>> f[:3] + l[-3:] #3
> Stack backtrace (innermost last):
> File "<stdin>", line 1
> TypeError: illegal argument type for built-in operation
> >>>
>
>
> Note that the statement marked #1 makes sense, but the answer
> ( #2 ) is incorrect.

#2 is a bug! Thanks for reporting this. It's fixed in 1.0...

> Expression #3 doesn't really make any sense when you understand
> the rationale of array types, but considering the relation at
> the top of the page, a PROGRAM ( as opposed to a reasonable
> person ) would have every right to expect it to work and NOT
> generate that exception. ( Let's assume that the program has
> tested type(arg1) == type(arg2) and that arg1 and arg2 both
> have the __getslice__ attribute, etc. )
>
>
> What are the pro's and con's of making:
> type(array('f')) == <type 'array-f'>
> type(array('l')) == <type 'array-l'>
> ... etc.

This would be awkward, since these types all share the same
implementation. Especially since I am hoping to generalize the array
type to support arrays of arbitrary structures. It is no coincidence
that the format string uses the same letters as the 'struct' module.

I don't think that in general a program can make some superficial
tests on an object and then assume to know all its properties. In
this case, the array type enforces an additional type check on
concatenation. With user-defined classes and new built-in types from
extensions, there is no limit to the restrictions that may apply.
E.g. a recently contributed "range" type supports repetition and
concatenation, but concatenation is only allowed if the arguments have
the same start, end and step parameters -- the implementation just
adds the repeat counts. As far as I am concerned this is completely
legal -- the type just isn't compatible with code that does arbitrary
concatenations.

Note that 'type', despite its name, is a low-level implementation-
related property of an object. You really want to talk about an
object's 'signature', which is a list of supported operations
augmented with any restrictions that apply. Unfortunately this is not
accessible to a program -- Python as a language is currently not
powerful to express such signatures in a useful manner. Although
Python doesn't support it in its syntax, my the model for type
compatibility is the following: a piece of code (e.g. a module, class,
or function) publishes the requirements on the data types passed into
it in the form of signatures. It is then an error to supply an object
whose signature isn't compatible with the required signature. Maybe
someday we can experiment with adding a form of signatures and
checking them at compile time (or at least at function entry time).

Until then, the only way to write code that catches every possible
stupidity of its caller is to write error-free code enclosed in a
generic exception handler :-)

--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>