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

enum protocol suggestion



In its current form I find the enum protocol inflexible and awkward.  It
is geared toward only being used as a common interface for collection
classes although it should be more generic

Methods like now-key and now-setter do not belong in an enumerator.
They assume that you are dealing with a collection, which is not
necessarily the case (for example when using <range> as an enum)

There are too many classes involved in creating an enum.  First you
have the collection class, then an enumeration class corresponding to
that collection class.  This forces enumerations such as range to define
2 classes when they don't even need 1

With a few minor changes enum could be used as a generic lazy iterator,
much like the stream type from ML or generators from python
(http://www.python.org/doc/2.2.2/whatsnew/node5.html)

I believe that an enumerator should simply be a thunk.  Each time the
thunk is called it returns the next item in the enumerator (keeping
state in a closure if necessary) until it reaches the end of the
enumeration, in which case an <enum-end> condition is signalled

A syntactic form like for should then only need to be modified to handle
an <enum-end> condition and call the thunk instead of using (fin?
enum) (now enum) (next enum) in a loop

The enum generic function for collections will look like

(dg enum (x|<any> => <Met>))

In order to make the interface to classless thunks look the same as
those returned by classes such as collections all that is required is to
add

(dm enum (x|<Met> => <Met>) x)

Now <range> and <range-enum> can be thrown away, implementing
enumerators are trivial

(dm below (lim|<num> => <Met>)
  (def x 0)
  { (if (>= x lim)
      (sig (new <enum-end>))
      (- (set x (+ x 1)) 1)) } )

Enumerations on existing collections are also quite trivial and do not
require a separate enum class

(dm enum (x|<lst> => <Met>)
  (def now nul)
  { (if (empty? x)
      (sig (new <enum-end>))
      (seq (set now (head x)) (set x (tail x)) now)) } )

This should encourage many more orthogonal uses of the enum protocol.
Files can be enumerated.  Enums over enums can be coded easily, I'd like
to see methods that take enums and split them into words or lines lazily