

GitHub - dcolascione/elisp-generators
source link: https://github.com/dcolascione/elisp-generators
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

GENERATORS NOW IN CORE
This package has been superseded by Emacs core support for generators in 25.1.
elisp-generators
This repository contains an implementation of Python-style generators for Emacs Lisp. It requires Emacs 24.3 or better.
Introduction
A generator is a kind of limited coroutine. When a program calls a generator function, the generator returns an iterator instead of a value. The code inside the generator routine is not run in this case. Instead, we run procedure code when users extract values from the returned iterator.
A program extracts values from an iterator by passing the iterator to
the next
function. When an iterator can generate no more values,
next
raises the stop-iteration condition, which callers must handle
using condition-case if not using a higher-level iteration construct.
next
accepts a single argument that defaults to nil. This argument
becomes the value to which yield
evaluates in the context of the
generator.
Generators supply values using the special yield
macro. When
yield
appears in a generator routine, it indicates that the iterator
we created when calling the generator routine should return that
value. Execution of the generator code is suspended at the point of
yield
until the next time someone calls the iterator. If nobody
calls next
, execution never resumes.
Each iterator gets its own control flow state and lexical environment. If one calls a generator function five times, the result is five independent iterators.
Dynamic environment
Generators do not capture the values of the current buffer, dynamic
variables, and so on before they return an iterator. From the point
of view of a generator, any state not lexically bound may appear to
change arbitrarily across a call to yield
. If generators need a
consistent environment while they generate values, they should
contractually require that callers preserve this environment or save
the environment themselves the way that a process filter might.
Allowed code
Generator definitions need to occur in files that make lexical-binding true. Code that merely uses a generator, however, can work with lexical-binding true or false.
Almost any Emacs Lisp code can appear inside a generator. One can
yield from inside a loop, inside a catch statement, or in any other
context. A generator can even generate an infinite sequence. yield
is legal inside catch
, inside condition-case
, and in almost any
other context.
There is one exception: generator routines may not yield is the
unwindforms portion of an unwind-protect
: it is not legal to yield
from inside one of these forms because the Lisp runtime does not give
us enough information to continue unwinding (in a generic way) after
suspending execution to return the yielded value from the iterator.
Note that is is legal to yield inside the bodyform (i.e., the first
form) of an unwind-protect
.
Simple usage
(assert lexical-binding)
(defgenerator mygenerator (i)
(yield 1)
(yield i)
(yield 2))
(let ((it (mygenerator 42)))
(assert (eql (next it) 1))
(assert (eql (next it) 42))
(assert (eql (next it) 2))
(assert (eq (condition-case nil
(next it)
(stop-iteration 'foo))
'foo)))
Convenience facilities
It would be inconvenient to write next
and condition-case
in every
context in which one might want to extract values from an iterator.
This library supplies a few convenience functions that make it easier
to work with iterators.
do-iterator
do-iterator
works like dolist
, except that it takes values from an
iterator, not a list.
(let (mylist)
(do-iterator (x (mygenerator 4))
(push x mylist))
(assert (equal mylist '(2 4 1))))
loop / cl-loop
This package also extends loop
with a new iteration keyword,
iterating
, that causes loop
to draw values from an iterator. This
keyword works the same way that on
and across
do.
(assert (equal (loop for x iterating (mygenerator 42)
collect x)
'(1 42 2)))
Recommend
-
78
README.md elisp-def
-
51
macros by example in elisp. Contribute to ijp/mbe.el development by creating an account on GitHub.
-
40
Readme.org Göktuğ’s Emacs Lisp Bits Introduction This repository is a swarm for all the Elisp stuff I published. Most files will have licen...
-
44
Join GitHub today GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
-
20
README.md SICP-in-Elisp SICP常读常新, 如绘画, 层层递进, 构图, 起形, 框架, 明暗, 光线... 反复阅读, 逐次夯建, 领会书中妙处. 假如SICP是el...
-
6
What's this? This is a extension of Emacs provides logging framework for Elisp. Feature Define function for logging automatically Write the following sexp in your elisp file. (log4e:deflogger "h...
-
15
uuidgen-el This is a naive implementation of RFC4122 Universally Unique IDentifier generation in elisp. Currently implemented are UUID v1 v3, v4 and v5 generation. The resolution of the time based UUID is microseconds, which is 10...
-
11
Read Me This library was created to fascilitate quickly building web pages, though it also includes tools for working with parsed xml Code Generation with esxml.el This library provides to formats for xml code generat...
-
11
Elisp API Demos Showing an Elisp demo of mapcar in C-h f mapcar: Usage To inject elisp demos into *Help*, such as C-h f (M-x describe-function), use...
-
9
yaml.el yaml.el is a YAML parser written in Emacs List without any external dependencies. It provides an interface similar to the Emacs JSON parsing utility. The functions provided are as follows: (yaml-parse-string s...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK