[Types-sig] Re: PRE-PROPOSAL: Python Interfaces
Guido van Rossum
guido@CNRI.Reston.VA.US
Sun, 22 Nov 1998 20:00:34 -0500
I think I understand John Skaller's argument better now. He's
objecting against the threat that (e.g.) functions which work fine
with any kind of -- abstractly defined -- integers might be littered
with 'int' declarations all over, restricting them to 32-bit machine
ints. His counterproposal (protocols) is very similar to Jim Fulton's
interfaces proposal, as many have noticed. There is probably some
truth in his fear -- those who like to add type annotations for
performance reasons (e.g. Jim Hugunin) would like to annotate code
with type declarations that will allow a compiler to generate the
"obvious" Java code.
I think we can dream up a sufficiently rich set of interfaces to make
everyone happy. For example, here's a bunch of numeric interfaces. I
envision that some of these can be combined to form various concrete
types. (We could also look at Scheme's numerical tower for
inspiration.)
0. number:
it is assumed that numeric types are embedded in each other in some
way (this is the Scheme numerical tower I think); they support
operators + - *, usually / and %, perhaps **, and possibly & | ~ ^
<< >> (it might make sense to define different interfaces depending
on which operators are supperted; some of the categories below
probably assume a certain set of operations)
1. complex vs. real:
real -- any subset of the real numbers (this includes ints and rationals)
complex -- has re and im fields (which are themselves real)
(Mike McLay will love the fact that this can be extended to include
quaternions and even higher-order numeric types)
2. exact vs. inexact:
exact -- e.g. integers and rationals; also fixed point
inexact -- floating point arithmetic
3. subdivisions of exact:
rational (arbitrary precision)
long (arbitrary precision)
int (32 bits)
short (16 bits)
byte (8 bits)
bit (1 bit)
fixed_decimal<n+m> -- a signed fixed decimal number with n digits
before and m digits after the decimal point
4. signed vs. unsigned:
for the fixed-size binary size integer types it may make sense to
recognize unsigned variants; these are effectively rings module
2**N
5. overflow behavior (only for fixed-size ints):
checked overflow -- raises OverflowError when results don't fit
unchecked overflow -- take results module 2**N (for example)
6. floating point (these are just examples)
float -- 32bit float
double -- 64bit float
extended -- 80bit float
Other categorizations are possible too (not clear if I'm stretching
the mechanism too far here):
- division behavior:
- exact result (rationals)
- approximate result (inexact, fixed_decimal)
- truncate towards zero (C/Java style ints)
- truncate towards -inf (Python style 32-bit ints)
- undefined (members of true rings)
- bit shift and mask operations:
- signed shifts
- unsigned shifts
- circular shifts
- undefined
Shifting gears, we can come up with a similar family of container and
string types (my colleagues at CNRI and Greg Stein will recognize some
of this from my scribbles on the whiteboard last Friday). The quoted
section from the C++ standard template library also applies here.
container:
- anything supporting __getitem__; probably also __len__
mutable vs. immutable (subclass of container):
- mutable has __setitem__ and perhaps __delitem__
- immutable may have __hash__ and comparisons
sequence vs. mapping (subclass of container):
- sequences require keys to be ints and support slicing
- mappings don't
Note that there could be a read-only mapping type.
I propose to add specific interfaces (perhaps "pseudolist" and
"pseudodict"?) for types that support all the additional methods that
lists resp. dictionaries have (append, sort, reverse, index, __in__
and some more for lists; has_key, keys, items, values, update, copy
for dictionaries). I don't even mind if there were (obscurely-named)
names for interfaces specifying some subsets of these, e.g. for a dict
that supports has_key and keys but not items or values, etc.
Gotta run,
--Guido van Rossum (home page: http://www.python.org/~guido/)