help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Using `iter-yield` with `seq.el` and mapping functions?


From: Michael Heerdegen
Subject: Re: Using `iter-yield` with `seq.el` and mapping functions?
Date: Tue, 08 Nov 2022 23:45:27 +0100
User-agent: Gnus/5.13 (Gnus v5.13)

Emanuel Berg <incal@dataswamp.org> writes:

> > Do you ask about the purpose of using iterators
>
> Yes?

(info "(elisp) Generators") (though the concept is not really explained
there).

It's mainly a form of abstraction.  If you process data, you model your
algorithm conceptually like

  iterate values --> filter or map values --> accumulate

with different stand-alone modules for each step (each step to be
understood in a broad sense, e.g. the last step could be "pick the
maximum").

An iterator enumerates a sequence of values (a related concept are
streams).  In Elisp, functions creating iterators are called
"generators".

An example: a function returning iterators that would enumerate the
leaves of a tree represented as a list structure could be defined like

(iter-defun iter-tree (list)
  (while list
    (let ((next (pop list)))
      (if (listp next) (iter-yield-from (iter-tree next))
        (iter-yield next)))))

Then

(setq my-iter-my-tree
     (iter-tree '(1 ((2 (3 4) 5) ((6 7) (8))) 9)))

would define a fresh iterator enumerating the leaves of the specified
tree:

(iter-next my-iter-my-tree) yields the values one by one:

(iter-next my-iter-my-tree)  ==> 1
(iter-next my-iter-my-tree)  ==> 2
                ...

Each iterator has its own individual state:

(setq my-iter-my-tree2
     (iter-tree '(1 ((2 (3 4) 5) ((6 7) (8))) 9)))

(iter-next my-iter-my-tree2) ==> 1
(iter-next my-iter-my-tree)  ==> 3

Iterators are (special) closures, they have a specific internal state.
You could say that the iter-defun code is stopped, or frozen, when you
yield, and continued at the exact same position, with the same "future
of computation", as had been left.  This future of computation is called
"continuation".

Continuations are implicit in generator.el: code is rewritten
automatically in a style that allows continuations to be created on the
fly.  `iter-next' just calls the continuation for the given iterator, so
to say.  In Scheme continuations are even first class objects.  You can
do a lot with them (also bad things).

Anyway, being able to return directly to a state in a program you have
just left is a nice thing - even when continuations are (only) implicit.
Allows to implement concurrency for example.  But even if you just want
data processing, the nice thing is that because of the automatic rewrite
(in CPS, "Continuation Passing Style"), you as a programmer are not
forced to write your code in a special style - you are freed from the
task of managing the "state" yourself.


Michael.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]