Differences between revisions 20 and 21
Revision 20 as of 2006-11-30 21:04:24
Size: 8938
Editor: JimJJewett
Comment: questions on interface examples
Revision 21 as of 2006-11-30 21:15:39
Size: 9251
Editor: JimJJewett
Comment: more questions
Deletions are marked like this. Additions are marked like this.
Line 121: Line 121:
###
# are you renaming __iter__ to iterator()?
###
Line 130: Line 134:
#######
# Don't you mean => Object
# (it *could* return itself)
#######
Line 132: Line 141:
 len () => Integer  len () => Integer
#####
# Why is length mandatory?
#####
Line 147: Line 159:
#######
# Don't you still mean => Boolean?
#######
Line 175: Line 191:
#########
# Are these methods all required? delete =/=> replace
#########

Possible Python 3K Class Tree?

This page contain an incomplete thinking-out-loud description of a re-factoring of the base and built-in Python types into a set of Abstract Base Classes (ABCs) and concrete types. This would probably be a good time to enumerate the exceptions various basic operations can raise, as well.

Some questions:

  • How to handle optional and keyword parameters to methods, such as the cmp parameter to the "sort" method on MutableSequence? Are they different methods with and without the parameter? Are they just keyword methods, and don't affect the method differentiation?

  • Should the MutableSequence interface be further broken up -- for instance, a deque may not be appropriate for sorting?

  • Currently, Boolean is a subtype of Integer, which is odd. But we still want a way to test any Object for "trueness". Should Boolean be an abstract type that's mixed-in to Object, or a concrete type that inherits from Object (thus implying that non-Boolean Objects may exist)? I've added a "true()" method to Object, which is simply a way of coercing it to a Boolean value (perhaps it should be called "boolean()").

  • Should destructive operations on MutableSequence return the sequence? They don't currently, but this would be very useful. I've made it so in this list...

  • Should None just be a very special instance of Object? Does the Null type need to exist?

  • If a file is opened in binary mode, should its iterator be over bytes instead of lines? Should "readline()" even work on a binary file?

Comparable:
 equals (Comparable) => Boolean

Object (Comparable):
 hash () => Integer
 # presumable for "is" we compare the ids of the two objects
 id () => Integer

##
# Why is id an integer?  That is convenient in current CPython
# (which never moves objects, so can use an address), but perhaps
# not in other implementations.  The only real requirement is that
# it be comparable (== and != -- I'm not even sure about sorting)
# to other ids.
##

 true () => Boolean
 # the __str__ method
 printable () => String

###
# huh?  Are you saying it has a __str__, or it meets a "printable"
# interface, or ..?
###

 class () => Type
 implements (Type) => Boolean

Type (Object):
 name () => String
 # supertypes yields list of immediate parent types (what's in __bases__)
 supertypes () => Sequence

###
# is it strictly a Sequence of Types?  (or types?) 
# (and/or interfaces?)
###

 # interfaces yields flattened list of all interface types this   
 # implements
 interfaces () => Sequence

Ellipsis (Object):
 # contains only the single value represented by three dots
 ThreeDots

Null (Object):
 # only a single value of this type
 None

################
# How is this different from None?  Or are you saying that the
# Null interface is like the NoneType?
################

Exception (Object):
 args () => Sequence

ExceptionContext (Object):
 exception () => Exception
 traceback () => Traceback

Boolean (Object):
 True
 False

Orderable:
 less_than (Object) => Boolean
 greater_than (Object) => Boolean
##
# What about <=, >=?
# Currently, only < is used for ordering
##

Numeric:
 add (Numeric) => Numeric
 subtract (Numeric) => Numeric
 product (Numeric) => Numeric
 quotient (Numeric) => Numeric
 floored_quotient (Numeric) => Numeric
 remainder (Numeric) => Numeric
 negate (Numeric) => Numeric
 absolute_value () => Numeric
 exponentiate (Numeric) => Numeric
 magnitude () => Numeric

Integer (Object, Orderable, Numeric):
 or (Integer) => Integer
 xor (Integer) => Integer
 and (Integer) => Integer
 shift (Integer) => Integer
 invert (Integer) => Integer
 real () => Real

Real (Object, Orderable, Numeric):
 floor () => Integer
 ceiling () => Integer

Complex (Object, Orderable, Numeric):
 conjugate () => Complex

Decimal (Object, Orderable, Numeric):
 TBD

Iterable:
 iterator () => Iteration

###
# are you renaming __iter__ to iterator()?
###

StringIterable:
 # yields an iteration of String values

KeyValueIterable (Iterable):
 # yields an iteration of key-value pairs 

Iteration (Object, Iterable):
 next () => other

#######
# Don't you mean => Object
# (it *could* return itself)
#######

# should Container be Iterable, or should that be reserved for real types, like Tuple?
Container (Iterable):
 len () => Integer   
#####
# Why is length mandatory?
#####
 contains (Object) => Boolean

Set (Container):
 is_subset (Set) => Boolean
 is_superset (Set) => Boolean
 union_with (Set) => Set
 intersection_with (Set) => Set
 difference (Set) => Set
 symmetric_difference (Set) => Set
 # should this be "multiply" to match Sequence?
 shallow_copy () => Set

Sequence (Container):
 contains (Sequence) => Sequence
#######
# Don't you still mean => Boolean?
#######

 # normal access via index
 # "end" defaults to start, "step" defaults to 1
 slice (Integer start, Integer end = None, Integer step = None) => Object
 # return self + other Sequence
 concatenate (Sequence) => Sequence
 # N shallow copies of self
 multiply (Integer) => Sequence

SequenceOfOrderable (Sequence):
 # do "min" and "max" make sense over arbitrary sequences?  Should really only apply to sequences of "Orderable"
 min () => Orderable
 max () => Orderable

MutableSequence (Sequence):
 append (Object) => self
 insert (Integer position, Object) => self
 # value at I is replaced with Object
 replace (Object, Integer position) => self
 # slice from I to J is replaced with values of Iterator
 replace (Iterable, Integer start, Integer end, Integer step = 1) => self
 extend (Object) => self
 count (Object) => Integer
 reverse ()
 index (Object, Integer start = 0, Integer end = len(self)) => Integer
 pop (Integer position = 0) => Object
 push (Object, Integer position = 0) => self
 delete (Integer start, Integer end = start, Integer step = 1) => self
 sort (Function comparison_fn = None, Function key_fn = None, Boolean reverse = False) => self
#########
# Are these methods all required?  delete =/=> replace
#########

ByteSequence (Object, Sequence):
 # should this be a MutableSequence?

Buffer (Object, MutableSequence):
 # is this just mutable version of ByteSequence?

String (Object, Sequence):
 TBD

Tuple (Object, Sequence):

List (Object, MutableSequence):

Mapping:
 get (Object key, Object default = None) => Object
 set (Object key, Object value)
 # should delete return the deleted value?  Why not.  That removes the need for "pop".
 delete (Object key) => Object
 clear ()
 # shallow copy of mapping
 copy () => Mapping
 contains (Object key) => Boolean
 # items returns a value which is guaranteed to satisfy both the Set interface and the KeyValueIterable interface
 items () => (Set and KeyValueIterable)
 keys () => Set
 values () => Set
 # get_or_set is the current "setdefault"
 get_or_set (Object key, Object value) => Object
 update (Mapping) => self
 # alternate form of "update" takes Iterable of key-value pairs
 update (KeyValueIterable) => self
 # yet another form takes no positional parameters, and arbitrary keyword arguments
 # I need a notation for this kind of method
 update (KWDS) => self
 # do we really need fromkeys?
 fromkeys (Sequence keys, Object initial_value) => Mapping

Dict (Object, Mapping, Container):
 # should some methods (e.g., "fromkeys") be here instead of in Mapping?

ExecutionContext:
 enter () => ExecutionContext
 exit (ExceptionContext) => Boolean

Stream:
 close ()

RandomAccessStream:
 # do we really need to continue to mimic the low-level UNIX seek and tell?
 # why not use Python sequence-style indices for offset?  Positive int for relative
 # to start, negative int for relative to end, and just call tell() and add an offset
 # if  you want to seek relative to the current location, for heaven's sake.
 seek (Integer offset)
 tell () => Integer
 
BinaryInputStream (Stream):
 # read tries to read the whole file, but may return just a part of it
 read () => ByteSequence
 read (Integer) => ByteSequence

OutputStream (Stream):
 flush()

BinaryOutputStream:
 write (ByteSequence) => Integer

TextStream:
 encoding () => String

TextOutputStream (OutputStream, TextStream):
 writeline (String) => Boolean
 writelines (StringIterable) => Boolean

TextInputStream (Stream, TextStream)
 readline () => String
 readlines () => StringIterable

DiskFile (RandomAccessStream):
 fileno () => Integer
 filename () => String
 isatty () => Boolean
 truncate (Integer size)
 mode () => String
 # It would be nice to have another method, "mimetype", which would try to guess
 # the MIME type for the file, and if it can it would return two strings, the MIME major
 # type and minor type for the file.  It would return None, None if it couldn't figure it out.
 # I'd suggest UNIX implementation just use "file", while Windows implementations
 # use registry and file extensions.
 # something like:  mimetype () => String, String


CategoryLanguage

AbstractBaseClasses (last edited 2008-11-15 13:59:38 by localhost)

Unable to edit the page? See the FrontPage for instructions.