Directory | Tags | Index | LinkIt | Submit   | Help
    Thursday, 18 October 2018 - anonymous
Login/Register to vote and to have access to more features

You are here: Root > By Topic > Language Extensions

View the dependency graph for this library

pygen - Python-style generators library
Created by vbuzuev on: Fri, 23 Feb 2007 05:03:59 GMT, Last modification: Sat, 24 Feb 2007 03:24:29 GMT
Web site
Mailing list
Version0.2 - Friday, 23 February 2007
OS compatibility
ASDF installableYes
Official Download
Mirrored Download
Source code repository

The library is a set of macros tries to emulate python's generators functionality in lisp.

One difference from the python's generators it is impossible to save a generator to a variable and call 'next' method manually. Only 'foreach' syntax is supported.

How it works

The reason of missed 'next' method is that pygen does not use real continuations to implement generators (as python does). It uses continuations idea only. Library's macros perform CPS transformation for FOREACH and YIELD forms.

Let see the code:
(defgenerator gen1()
  (yield 1)
  (yield 2)
  (yield 3))

(defun use-generator ()
  (foreach x in gen1()
    (print x)))

Normal thinking of the code is: OK, call gen1(), save the return value into a variable 'x' and call print(x); call gen1() again and do the same; cal gen1() again, again, again... In short, 'foreach' is a master and 'generator' is a slave - master calls slave while slave has a job to do.

But we can thing a little bit different: OK, we know what we are going to do with the generator's value - run the body of FOREACH form ((print x) in our case). So, it is possible to pass that code to a generator and the generator will call it when needed. The generator becomes a master and foreach becomes a slave. We can think about a generator as a normal function that receives additional parameter - what to do with the result value aka continuation. By pygen's macros the code above is transformed into something like this:

(defun gen1 (*cont*)
  (funcall *cont* 1)
  (funcall *cont* 2)
  (funcall *cont* 3))

(defun use-generator ()
  (gen1 #'(lambda (x) (print x))))

When to use

If a generator function is simple that means it is relatively easy to save and and restore the function's state in a closure it might be more appropriate to use series package or some other lazy-lists package. For someone it could be more convenient to pass a functional parameter represented a continuation to a generator directly. Pygen is doing well when a generator function is a quite complex, e.g. there are several inner loops or when it is needed to work with 'unwind-protect' resources such as files. For example, SAX and pull XML parsers could be implemented using generators.


Generators are an abstraction. If it is suitable for you - pygen is here :)

Compatible Implementations

Allegro Common Lisp | SBCL


Language Extensions | Python | Implementations | ASDF installable | Libraries

0 Notes and 0 comments

0 Notes

You must be logged to add a note


You must be logged to add a comment