Rotating generator (a generator factory pattern)

Q&A's, tips, howto's

Rotating generator (a generator factory pattern)

Postby Alisaxy » 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:
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))))))

slightly more concise eval version:
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)))))))))

usage:
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))

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


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.
Last edited by Alisaxy on Sun Aug 02, 2015 2:34 pm, edited 2 times in total.
Alisaxy
 
Posts: 3
Joined: Tue Jul 28, 2015 7:12 pm

Re: Rotating tasklet (a tasklet factory pattern)

Postby ralph.ronnquist » Sun Aug 02, 2015 2:07 am

Nice idea. I assume the 'rot in setting rotX should be 'rotX rather.

Though maybe you would call these "generators" rather than "tasklets"? Or, focussing on that they provide different behaviour upon each invocation, maybe you'd call it state machine; with something for conditional branching, you'll have a Turing machine.

Anyhow, self modifying code is always fun.
ralph.ronnquist
 
Posts: 208
Joined: Mon Jun 02, 2014 1:40 am
Location: Melbourne, Australia

Re: Rotating tasklet (a tasklet factory pattern)

Postby Alisaxy » Sun Aug 02, 2015 12:17 pm

ralph.ronnquist wrote:Nice idea. I assume the 'rot in setting rotX should be 'rotX rather.


Oops, a typo! Yeah, should be "rotX" or any location to the generator in question. Could be a path to a list element like this "(list-name 0)". Yes, "generator" would be more appropriate, since tasklets are basically software thread emulations whilst generators are just yielding functions.
Alisaxy
 
Posts: 3
Joined: Tue Jul 28, 2015 7:12 pm


Return to newLISP in the real world

Who is online

Users browsing this forum: No registered users and 2 guests

cron