Rotating generator (a generator factory pattern)
Posted: Sat Aug 01, 2015 4:09 pm
I was trying to wrap my head around all of the power newLISP offers, figuring that the lack of coroutines or tasklets which I very much need, wouldn't be much of a problem to fix. It appears I was right and here's a slightly more advanced rotating generator factory pattern. One could easily adopt it for any type of a generator factory. Who needs "yield", right?
self-modifying version:
slightly more concise eval version:
usage:
Not sure which version is better. I have a sub-conscious distrust for eval (all those years using js in my day job), but it is probably the better version. I anticipate though that the first version would be more elegant if the function would become more complex.
slightly shorter no eval version using setf instead of pop/push
Just a suggestion: a way to refer to the function itself in an $it fashion would make newLISP an even more powerful language. Right now if you wish to relocate or copy such construct you would have to provide it with a precise future location, which can get unwieldy and just isn't all that elegant to be honest. With a let's call it a "$self" one could forgo such needless gymnastics.
EDIT: incorporated setf into all patterns.
self-modifying version:
Code: Select all
(setf rotating-tasklet^ (fn (loc body)
(rotate body)
(letex (loc loc body body)
(expand (setf loc (fn (arg)
(pop loc -1)
(push (first (rotate 'body -1)) loc -1)
'first-of-body-goes-here))))))
Code: Select all
(setf rotating-tasklet^ (fn (loc body)
(rotate body)
(letex (loc loc body body)
(expand (setf loc (fn (arg)
(eval (first (rotate 'body -1)))))))))
Code: Select all
(rotating-tasklet^ 'rot
'((+ 10 arg)
(+ 11 arg)
(+ 12 arg)))
(rotating-tasklet^ 'rotX
'((println "first")
(println "second")
(println "third")))
(rotX)
(println (rot 1000))
(rotX)
(println (rot 2500))
(rotX)
(println (rot 333))
slightly shorter no eval version using setf instead of pop/push
Code: Select all
(setf rotating-tasklet^ (fn (loc body)
(rotate body)
(letex (loc loc body body)
(expand (setf loc (fn (arg)
(setf (last loc) (first (rotate 'body -1)))
'first-of-body-goes-here))))))
EDIT: incorporated setf into all patterns.