[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

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

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.

  - 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/)