From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Michael Heerdegen Newsgroups: gmane.emacs.devel Subject: Re: Generator Examples Date: Sun, 25 Sep 2016 02:16:45 +0200 Message-ID: <87y42gltoy.fsf@web.de> References: <22499.10814.549580.139539@gargle.gargle.HOWL> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1474762667 1245 195.159.176.226 (25 Sep 2016 00:17:47 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 25 Sep 2016 00:17:47 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux) Cc: emacs-devel@gnu.org To: raman@google.com Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Sep 25 02:17:44 2016 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bnx8S-0007QD-Lq for ged-emacs-devel@m.gmane.org; Sun, 25 Sep 2016 02:17:36 +0200 Original-Received: from localhost ([::1]:36056 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bnx8Q-0007bJ-Nj for ged-emacs-devel@m.gmane.org; Sat, 24 Sep 2016 20:17:34 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:55834) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bnx7q-0007bC-RE for emacs-devel@gnu.org; Sat, 24 Sep 2016 20:17:00 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bnx7k-0005WD-Qb for emacs-devel@gnu.org; Sat, 24 Sep 2016 20:16:57 -0400 Original-Received: from mout.web.de ([212.227.17.11]:58409) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bnx7k-0005Ve-GK for emacs-devel@gnu.org; Sat, 24 Sep 2016 20:16:52 -0400 Original-Received: from drachen.dragon ([90.186.0.76]) by smtp.web.de (mrweb103) with ESMTPSA (Nemesis) id 0MLxwG-1btRIi2gIe-007lyj; Sun, 25 Sep 2016 02:16:49 +0200 In-Reply-To: <22499.10814.549580.139539@gargle.gargle.HOWL> (raman@google.com's message of "Wed, 21 Sep 2016 17:47:58 -0700") X-Provags-ID: V03:K0:Pmj06IYEvyENB4+5AN7h5NXkXO8Q3VLq/iZgCrAGlxzXRtiF+25 58I+P65MOHfgfRv2CxGaQWpB923LCOWwHSbAXv3G0fK3uTF5afUo4HrloBTy754Qxyc0BSJ hlfOS2Kr/s4BILfiYzkWtm48UOnKkWnrtei2Xn3MPehMvuUkotlRN5R/llntD+TscR/HFo7 M2j4V3dHJHdftKcE9ZMzw== X-UI-Out-Filterresults: notjunk:1;V01:K0:npYUDeVOGiU=:CbrDYiuBhhBDii2szKZP3X CjiQ4hhu3XMrY97UFLYP1jWBoqdJvNHf9tEbd9ySPUIcXy3vXn68HQ5I2cSSESlS4XYRr5vJ4 TxT6bJ0PE89XwtJkvLk3OBKYx7ESlC2oa8y9JlkWQMhy7Ro2gWtUaywMd3vCJjM4cXRAuFe44 T6VIzCjg1306hEzJuMkxCEnRDuv91cplEAR0NGlgeQwfCRxJ6Qc6Rbc7NZRMemIQAq/4bYuRw sZOj4nunEORZCX8ePz6klukGMYGI2NScHlhahxfBDicu95yStD8NySebew1a60nroVF45vr15 sTe61EOQaiBr+8Og12RMxE9UJF/s8jJEdc89oZqGxJFGCYw/NZ670EIX9vbbPOvtFjle4XuO+ HtlZVNdaSCun7aX5vzFy/6S24q2AaYyp39bvZlL8zetwdVFuDTWs4zbxV80ovupSN57xL7j6x In8x9rBs0dfPt07AeTi7UePLmD32Uo7rXjHG8zjsKEyq3dWGgn4txUYHLHNKXx3xf+pn+nP/E 3lAcV3SVwxRhVCUbfCO7smoA+y2qKZYiOxliVOwHvoPnFvwoKW9ccfKxrQ4a0IrdMeOqR8ZBr wbclrhTOZTVM8uu1ipvvt/Kb9egR0Cu8fyIrO6EDTG4l1r5X03xTDirlMv/cQqUUBUie6mJZE PIpJF5OUHZ4Lw9Lz7Fl66OYDIkEjicxj4SNBomRZgD++UWhGy3sl15ex8DwLYU8yptAX6kTVr dgky/Qb3lQtAwqgWa6yaIZS0ddngPoF2am30ZnBDJ2fCh8pyRjD/Hl12nKrAvuHpSUSz0LHk X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 212.227.17.11 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:207770 Archived-At: Hey raman, > I'm attaching a short texinfo file containing a couple of examples of > using generators in Emacs Lisp. Great. This would be an improvement for the manual indeed. > The texinfo manual contains one example which I found confusing in > parts: Yeah, the current doc is more for people already familiar with the concept. > 1. The example has a nested call to iter-yield -- not sure why Just to demonstrate how it behaves, I think. It's probably not very common/useful in practise. > 2. I still dont quite understand the purpose of the optional argument > to iter-next, an example that leverages it would be good to have. I think it's more useful if you think of generators as coroutines. A simple real life example would be: you have implemented a counter as a generator (generating 1, 2, ...), and when you restart it, you want to add a certain increment to its count so far before continuing. > @lisp > (iter-defun fibonacci-iter () > "Return a Fibonacci sequence generator." > (let ((a 1) > (b 1)) > (while t > (iter-yield a) > (cl-psetq a b b (+ a b ))))) > @end lisp Looks good (but could we get rid of the a bit uncommon `cl-psetq'). I remember that the suggested convention was to call the iter-defun a generator, and the return value an iterator (in this regard, the docstring would be wrong). FWIW, some time ago a had posted a similar example, implementing a generator of the prime numbers: (iter-defun cross-through-multiples-of (n) "Repeat indefinitely: Return `t' N-1 times, then return `nil' once." (let ((i (1- n))) (while t (if (zerop i) (progn (setq i (1- n)) (iter-yield nil)) (iter-yield t) (cl-decf i))))) (iter-defun make-prime-gen () "Return a generator of the prime numbers." (let ((n 2) (sieve '())) (while t (when (cl-every #'identity (mapcar #'iter-next sieve)) ;; a new prime! (push (cross-through-multiples-of n) sieve) (iter-yield n)) (cl-incf n)))) > A generator that takes a list and returns an iterator over that list: > > @lisp > (iter-defun list-iter (l) > "Return an iterator that iterates over list `l'." > (let ((local(copy-sequence l))) > (while local (iter-yield (pop local))))) > @end lisp Isn't the `copy-sequence' redundant (popping the local variable doesn't alter the original list)? > @lisp > ;;; Create a list iterator: > > (setq l-iter (list-iter '(a b c d e))) > ;;; Loop through the iterator, collecting values: > (cl-loop for e iter-by l-iter collect e) > @end lisp > > @bye To improve the doc even further, I think it would be good if we could as well: - Underline the difference between generators and its "instances" (iterators), and that multiple iterators of the same "type" have independent inner states. - Have an example that doesn't create lists at the end, to underline that it is a different concept, and/or - Have a real life example (something like tree traversal, e.g. a generator of directory files or so) that is an improvement compared to using list. Regards, Michael.