[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