all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: Michael Heerdegen <michael_heerdegen@web.de>
Cc: Daniel Colascione <dancol@dancol.org>,
	Emacs Development <emacs-devel@gnu.org>
Subject: Re: Generators (iterators) for Gnu Emacs
Date: Thu, 04 Dec 2014 20:55:21 -0500	[thread overview]
Message-ID: <jwvegse7voi.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <877fy77zhp.fsf@web.de> (Michael Heerdegen's message of "Fri, 05 Dec 2014 00:43:14 +0100")

> I want to contribute a package about generators to Gnu Emacs.

Thanks.  Looks good.  I generally prefer adding packages to GNU ELPA,
but I guess it also makes sense to add this directly to Emacs.

> Daniel Colascione suggested to me to rename the thing to "iterators.el",
> since this package doesn't use continuation passing style to implement
> "yield".  I guess that's reasonable.

I don't have any opinion on the naming.  A few comments below.


        Stefan


> ;;; Commentary:

Please state clearly which are all the basic operations one can perform on
a generator (AFAICT there's only one such operation, which is `gen-next').

It's great to see that you haven't needed anything else than `gen-next'.
I'd have expected a `gen-done-p' test to be needed/handy every once in
a while.

> (defmacro gen-make (&rest body)
>   "Return a generator that evaluates BODY to generate elements.
> For each call of `gen-next' with the the returned generator, BODY
> will be evaluated to produce an element."
>   (let ((this-element (make-symbol "this-element")))
>     `(let (,this-element)
>        (lambda ()

AFAICT this requires lexical-binding in the caller, so we might want to
signal an error if lexical-binding is nil.

>          (if (eq ,this-element 'gen-done)
>              'gen-done
>            (setq ,this-element (progn ,@body)))))))

This code breaks down if your generator happens to return the symbol
`gen-done'.  A better option is to have a (defconst gen-done <val>)
where the value is unique w.r.t `eq' (can be a string, a cons cell, an
uninterned symbol, you name it) and then to use this value rather than
hard-coding an interned symbol.

> (defun gen-next (generator)
>   (funcall generator))

A defalias would be more efficient.

>    (if (not (null elements))

Aka (if elements

> The sequence of returned elements is starting with VALUE. Any
                                                          ^^^
Add extra space (or break the line).

> successive element will be found by calling FUNCTION on the
> preceding element."
>   (gen-append
>    (gen-from-elts value)
>    (gen-make (setq value (funcall function value)))))

I guess a `gen-cons' would be more efficient than this 
(gen-append (gen-from-elts value) ...).

> (defun gen-number-range (&optional start end inc)
>   "Return a generator of a number sequence.
> START denotes the first number and defaults to 1.

Tradition in computer science is to start counting from 0.  There are
some notable exceptions (such as `point-min', which I regret), but
I strongly recommend to follow the tradition.

> The second optional argument END specifies the upper limit.  If nil,
> the returned generator is infinite.  INC is the increment used between
> numbers and defaults to 1."

Please be more precise about whether END is included or excluded.
Tradition (see again) is to exclude the upper bound (e.g. in dotimes).

> (defmacro gen-delay-expr (expression)

Have you made use of this?  I'm not sure it really fits.  I mean,
technically it works, but I'm not completely sure if pretending it's
a generator is a clever idea or not.

>   (let ((done nil) el)
>     (gen-make
>      (if done 'gen-done
>        (setq el (gen-next generator))
>        (while (and (not (eq el 'gen-done))
>                    (not (funcall predicate el)))
>          (setq el (gen-next generator)))
>        (if (eq el 'gen-done)
>            (setq done 'gen-done)
>          el)))))

Better move the `el' into the `gen-make' so it's not caught as a free
variable of the closure.  And please apply de-Morgan's law.

>     (let ((current (pop generators)) el (done nil) (skip (make-symbol "skip")))
>       (gen-delq
>        skip
>        (gen-make 
>         (if done 'gen-done
>           (setq el (gen-next current))
>           (if (eq el 'gen-done)
>               (if (null generators)
>                   (progn (setq done t) 'gen-done)
>                 (setq current (pop generators))
>                 skip)
>             el)))))))

Same here: sink `el' into the `gen-make'.

>   (nreverse (gen-reduce (lambda (x y) (cons y x)) () generator)))

Too bad the order of arguments was not swapped so we could use #'cons
instead of this lambda.

>   "Return true if PREDICATE is true for any element of GENERATOR."
            ^^^^
We call it "non-nil".  Same for `gen-every'.

>   (cl-callf or function #'identity)
>   (gen-max generator (and function (lambda (x) (- (funcall function x))))))

AFAICT, the first line makes sure `function' is not nil, so you can
remove the "(and function" on the second line.



  reply	other threads:[~2014-12-05  1:55 UTC|newest]

Thread overview: 85+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-04 23:43 Generators (iterators) for Gnu Emacs Michael Heerdegen
2014-12-05  1:55 ` Stefan Monnier [this message]
2014-12-05  2:42   ` Leo Liu
2014-12-05  3:23     ` Daniel Colascione
2014-12-05  3:32       ` Leo Liu
2014-12-05  4:19         ` Stefan Monnier
2014-12-05  8:52           ` Leo Liu
2014-12-05 14:40             ` Stefan Monnier
2014-12-05 14:48             ` Stefan Monnier
2014-12-05 15:34               ` Daniel Colascione
2014-12-05 18:32                 ` Stefan Monnier
2014-12-05 22:08                   ` Daniel Colascione
2014-12-06  9:38                     ` Stephen J. Turnbull
2014-12-05 22:08                   ` Daniel Colascione
2014-12-05 22:08                   ` Daniel Colascione
2014-12-05 22:08                   ` Daniel Colascione
2014-12-05 22:08                   ` Daniel Colascione
2014-12-05 22:08                   ` Daniel Colascione
2014-12-05 22:08                   ` Daniel Colascione
2014-12-05 22:08                   ` Daniel Colascione
2014-12-05 22:08                   ` Daniel Colascione
2014-12-05  9:54   ` David Kastrup
2014-12-05 14:51     ` Stefan Monnier
2014-12-05 17:12       ` Michael Heerdegen
2014-12-05 18:34         ` Stefan Monnier
2014-12-05 19:06           ` Michael Heerdegen
2014-12-06  3:53             ` Stefan Monnier
2014-12-05 18:01   ` Michael Heerdegen
2014-12-05 19:19     ` Stefan Monnier
2014-12-05 22:54       ` Michael Heerdegen
2014-12-05  5:47 ` Thierry Volpiatto
2014-12-05 14:49   ` Stefan Monnier
2014-12-05 17:20     ` Michael Heerdegen
2014-12-05 19:16       ` Stefan Monnier
2014-12-05 22:26         ` Daniel Colascione
2014-12-06  0:13           ` Michael Heerdegen
2014-12-06  0:22             ` Michael Heerdegen
2014-12-06  4:09           ` Stefan Monnier
2014-12-06  9:12             ` Daniel Colascione
2014-12-06 22:24               ` Stefan Monnier
2014-12-07  3:10                 ` Daniel Colascione
2014-12-07  6:12                   ` Stefan Monnier
2014-12-07  7:51                     ` Daniel Colascione
2014-12-07 16:22                       ` Ted Zlatanov
2014-12-07 17:40                         ` Namespace macros (was: Generators (iterators) for Gnu Emacs) Helmut Eller
2014-12-08  0:11                           ` Artur Malabarba
2014-12-08  7:55                             ` Namespace macros Helmut Eller
2014-12-08  8:36                               ` Artur Malabarba
2014-12-08  9:17                                 ` Helmut Eller
2014-12-08 11:02                                   ` Artur Malabarba
2014-12-08 11:21                                     ` Dmitry Gutov
2014-12-08 11:42                                       ` Artur Malabarba
2014-12-08 11:52                                         ` Dmitry Gutov
2014-12-08 12:52                                     ` Helmut Eller
2014-12-08 20:59                                       ` Richard Stallman
2014-12-08 23:37                                         ` Artur Malabarba
2014-12-09  0:25                                         ` Helmut Eller
2014-12-07 18:30                         ` Generators (iterators) for Gnu Emacs Drew Adams
2014-12-08  0:25                         ` Richard Stallman
2014-12-08  1:21                           ` Daniel Colascione
2014-12-08  5:34                             ` Drew Adams
2014-12-08 20:59                               ` Richard Stallman
2014-12-08 21:48                                 ` Stefan Monnier
2014-12-09 19:35                                   ` namespaces Ivan Shmakov
2014-12-08 20:59                             ` Generators (iterators) for Gnu Emacs Richard Stallman
     [not found]                         ` <<E1Xxm91-0000jQ-Mr@fencepost.gnu.org>
     [not found]                           ` <<5484FD09.60603@dancol.org>
     [not found]                             ` <<9ae6762d-a52a-4a06-b2e9-dab893a22d38@default>
     [not found]                               ` <<E1Xy5Os-0004cU-HF@fencepost.gnu.org>
2014-12-08 21:17                                 ` Drew Adams
2014-12-07 16:51                       ` Stefan Monnier
2014-12-07 17:29                         ` Nic Ferrier
2014-12-07 21:17                           ` Stefan Monnier
2014-12-07 21:26                             ` Nic Ferrier
2014-12-07 21:32                             ` Daniel Colascione
2014-12-07 21:43                               ` Drew Adams
2014-12-07 23:31                               ` Stefan Monnier
2014-12-07 23:39                                 ` Daniel Colascione
2014-12-08  2:23                                   ` Stefan Monnier
2014-12-08  2:24                                     ` Daniel Colascione
2014-12-08  3:23                                       ` Stefan Monnier
2014-12-08 10:01                                         ` Thien-Thi Nguyen
2014-12-08 20:35                                         ` David Engster
2014-12-08 21:45                                           ` Stefan Monnier
2014-12-08  0:18                                 ` Dmitry Gutov
2014-12-08  2:25                                   ` Stefan Monnier
2014-12-08  2:55                                     ` Dmitry Gutov
2014-12-07  8:54                 ` David Kastrup
2014-12-07  9:25                   ` Stephen J. Turnbull
     [not found] <<877fy77zhp.fsf@web.de>

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=jwvegse7voi.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=dancol@dancol.org \
    --cc=emacs-devel@gnu.org \
    --cc=michael_heerdegen@web.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.