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

Re: enum protocol suggestion



Smelly Pooh <plop+goo@redbrick.dcu.ie> writes:

> 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

i agree it could 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)

perhaps this just argues for different classes of enums.  i was trying
to not have too many classes.  i figured that they could go
unimplemented for collections not supporting this bit of protocol. 

> 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

i must say that this is a rare thing.  first of all, enum's were meant
to be the basic building block of collections, where you do need at
least a collection.  this comes from dylan where defining a collection
amounted to mostly just defining its iteration protocol.  this makes
it quite easy to add collections.  note that sometimes you have the
flip side where you can reuse an enumerator, such as <flat-enum>, when
creating a subclass of <flat>.

another point is that range collections are useful elsewhere.  they
can be used as arguments for all functions that take collections.

> 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

i'm definitely sympathetic to this, but i too am reluctant to use
conditions to signify end of enumeration.

perhaps a better solution is to introduce convenient syntax for
defining these enums.  i haven't yet worked this out, but this has
been the plan all along.  i also like the coroutine solutions to this
but wasn't willing to introduce this complexity to goo.

i guess other solutions are to pass in an enum-end function to call in
case of enum-end.

i think enum's could be generalized by just loosening up their
parameter type:

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

this allow enum's to enum things other than collections.

i think one problem is that goo is one part object and one part
function.  i agree that enum's are still a bit more involved than i'd
like but better than dylan.

thanks for your comments.  more later.

-- jonathan

> 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