unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Using `iter-yield` with `seq.el` and mapping functions?
@ 2022-11-05 21:28 Okamsn
  2022-11-06  0:39 ` Michael Heerdegen
  2022-11-09  1:29 ` Michael Heerdegen
  0 siblings, 2 replies; 8+ messages in thread
From: Okamsn @ 2022-11-05 21:28 UTC (permalink / raw)
  To: help-gnu-emacs

Hello,

Is it possible to use `iter-yield` via mapping functions and `seq.el`
functions? For example, when I do

     (setq iter-maker (iter-lambda (x)
                        (seq-doseq (item x)
                          (iter-yield item))))
     (setq my-iter (funcall iter-maker '(1 2 3)))
     (iter-next my-iter)

I get an error "(void-function cps-internal-yield)".

When I try

     (setq iter-maker (iter-lambda (x)
                        (seq-do #'iter-yield x)))
     (setq my-iter (funcall iter-maker '(1 2 3)))
     (iter-next my-iter)

I get the error "(error "‘iter-yield’ used outside a generator")".

These are both with lexical binding enabled on Emacs 28.1.

Can iterators be used with these functions and other mapping functions,
such as `mapatoms`, `mapc`, and the like?

Thank you.




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Using `iter-yield` with `seq.el` and mapping functions?
  2022-11-05 21:28 Using `iter-yield` with `seq.el` and mapping functions? Okamsn
@ 2022-11-06  0:39 ` Michael Heerdegen
  2022-11-07  2:02   ` Michael Heerdegen
  2022-11-09  1:29 ` Michael Heerdegen
  1 sibling, 1 reply; 8+ messages in thread
From: Michael Heerdegen @ 2022-11-06  0:39 UTC (permalink / raw)
  To: help-gnu-emacs

Okamsn <okamsn@protonmail.com> writes:

> Is it possible to use `iter-yield` via mapping functions and `seq.el`
> functions? For example, when I do
>
>      (setq iter-maker (iter-lambda (x)
>                         (seq-doseq (item x)
>                           (iter-yield item))))
>      (setq my-iter (funcall iter-maker '(1 2 3)))
>      (iter-next my-iter)
>
> I get an error "(void-function cps-internal-yield)".

Good question.  `dolist' works.  A rewrite using `mapc' doesn't (same
error).

Michael.




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Using `iter-yield` with `seq.el` and mapping functions?
  2022-11-06  0:39 ` Michael Heerdegen
@ 2022-11-07  2:02   ` Michael Heerdegen
  2022-11-07 12:31     ` Emanuel Berg
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Heerdegen @ 2022-11-07  2:02 UTC (permalink / raw)
  To: help-gnu-emacs; +Cc: Stefan Monnier

Michael Heerdegen <michael_heerdegen@web.de> writes:

> Good question.  `dolist' works.  A rewrite using `mapc' doesn't (same
> error).

Stefan, do you maybe know whether

#+begin_src emacs-lisp
(iter-next
 (funcall
  (iter-lambda (l)
    (mapc (lambda (y) (iter-yield y))
          l))
  '(1 2 3)))
#+end_src

is expected to error?

A rewrite using `dolist' works as expected:

#+begin_src emacs-lisp
(iter-next
 (funcall
  (iter-lambda (l)
    (dolist (y l) (iter-yield y)))
  '(1 2 3)))
#+end_src


Michael.




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Using `iter-yield` with `seq.el` and mapping functions?
  2022-11-07  2:02   ` Michael Heerdegen
@ 2022-11-07 12:31     ` Emanuel Berg
  2022-11-07 14:08       ` Michael Heerdegen
  0 siblings, 1 reply; 8+ messages in thread
From: Emanuel Berg @ 2022-11-07 12:31 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

> (iter-next
>  (funcall
>   (iter-lambda (l)
>     (dolist (y l) (iter-yield y)))
>   '(1 2 3)))

Hm, what's the advantage or increased expressibility with
this method?

-- 
underground experts united
https://dataswamp.org/~incal




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Using `iter-yield` with `seq.el` and mapping functions?
  2022-11-07 12:31     ` Emanuel Berg
@ 2022-11-07 14:08       ` Michael Heerdegen
  2022-11-07 16:50         ` Emanuel Berg
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Heerdegen @ 2022-11-07 14:08 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <incal@dataswamp.org> writes:

> Michael Heerdegen wrote:
>
> > (iter-next
> >  (funcall
> >   (iter-lambda (l)
> >     (dolist (y l) (iter-yield y)))
> >   '(1 2 3)))
>
> Hm, what's the advantage or increased expressibility with
> this method?

Do you ask about the purpose of using iterators, or do you ask why the
above call doesn't error like the one having the issue?

Michael.




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Using `iter-yield` with `seq.el` and mapping functions?
  2022-11-07 14:08       ` Michael Heerdegen
@ 2022-11-07 16:50         ` Emanuel Berg
  2022-11-08 22:45           ` Michael Heerdegen
  0 siblings, 1 reply; 8+ messages in thread
From: Emanuel Berg @ 2022-11-07 16:50 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

>>> (iter-next
>>>  (funcall
>>>   (iter-lambda (l)
>>>     (dolist (y l) (iter-yield y)))
>>>   '(1 2 3)))
>>
>> Hm, what's the advantage or increased expressibility with
>> this method?
>
> Do you ask about the purpose of using iterators

Yes?

-- 
underground experts united
https://dataswamp.org/~incal




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Using `iter-yield` with `seq.el` and mapping functions?
  2022-11-07 16:50         ` Emanuel Berg
@ 2022-11-08 22:45           ` Michael Heerdegen
  0 siblings, 0 replies; 8+ messages in thread
From: Michael Heerdegen @ 2022-11-08 22:45 UTC (permalink / raw)
  To: help-gnu-emacs

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.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Using `iter-yield` with `seq.el` and mapping functions?
  2022-11-05 21:28 Using `iter-yield` with `seq.el` and mapping functions? Okamsn
  2022-11-06  0:39 ` Michael Heerdegen
@ 2022-11-09  1:29 ` Michael Heerdegen
  1 sibling, 0 replies; 8+ messages in thread
From: Michael Heerdegen @ 2022-11-09  1:29 UTC (permalink / raw)
  To: Okamsn; +Cc: help-gnu-emacs, Stefan Monnier

Okamsn,

I have opened Bug#59140 "iter-yield from lambda" about this.  Thanks
for bringing this up.

I think one can only work around the issue for now e.g. by using a
`while' loop instead.

Michael.



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-11-09  1:29 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-05 21:28 Using `iter-yield` with `seq.el` and mapping functions? Okamsn
2022-11-06  0:39 ` Michael Heerdegen
2022-11-07  2:02   ` Michael Heerdegen
2022-11-07 12:31     ` Emanuel Berg
2022-11-07 14:08       ` Michael Heerdegen
2022-11-07 16:50         ` Emanuel Berg
2022-11-08 22:45           ` Michael Heerdegen
2022-11-09  1:29 ` Michael Heerdegen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).