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

Re: enum protocol suggestion




On Saturday, November 16, 2002, at 09:35  PM, Smelly Pooh wrote:
> I believe that an enumerator should simply be a thunk.
Ah, but you can do just as good now...with the following small amount 
of code, you now have a function "funenum" (I would have defined a 
method on "enum" but it is currently overly restricted to <col>) which 
takes a thunk and returns an enumerator.

(dv $end-marker (gensym))
(dc <fun-enum> (<enum>))
(dp %dafun (<fun-enum> => <fun>))
(dp %curval (<fun-enum> => <any>))

(dm funenum (x|<fun> => <fun-enum>)
   (new <fun-enum> %dafun x %curval (x)))

(dm now (e|<fun-enum> => <any>)
   (%curval e))

(dm nxt (e|<fun-enum> => <fun-enum>)
   (renew e %curval ((%dafun e))))

(dm fin? (e|<fun-enum> => <log>)
   (== (%curval e) $end-marker))


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

(dm below (lim|<num> => <enum>)
   (def x 0)
   (funenum
     { (if (>= x lim)
         $end-marker
         (- (set n (+ n 1)) 1)) } ))

The downside of returning an enum is that you cannot do collection 
operations on it. For example, with GOO's current definition of below 
you can do things like (any? {x . (= x 5)} (below 5)). The other 
downside is that this leaves no room for easily switching to a 
non-mutating enumerator system at any point, as all the state is 
implicitly stashed away inside a closure instead of explicitly stored 
in the actual enumerator...I suppose if there was support for copying 
closures...but...

James