From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Nala Ginrut Newsgroups: gmane.lisp.guile.devel Subject: Re: [PATCH] Move let/ec to top-level Date: Sat, 6 Apr 2013 10:53:48 +0800 Message-ID: References: <87wqsspmtk.fsf@gnu.org> <1365056340.2755.5.camel@Renee-desktop.suse> <87bo9s8opj.fsf@Kagami.home> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=e89a8ff2566816c98b04d9a850f2 X-Trace: ger.gmane.org 1365278523 28285 80.91.229.3 (6 Apr 2013 20:02:03 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 6 Apr 2013 20:02:03 +0000 (UTC) Cc: =?UTF-8?Q?Ludovic_Court=C3=A8s?= , guile-devel To: Ian Price Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sat Apr 06 22:02:00 2013 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UOZIy-0007UX-GG for guile-devel@m.gmane.org; Sat, 06 Apr 2013 22:01:40 +0200 Original-Received: from localhost ([::1]:47426 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UOJGX-000053-9d for guile-devel@m.gmane.org; Fri, 05 Apr 2013 22:54:05 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:38057) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UOJGO-0008Oy-Fg for guile-devel@gnu.org; Fri, 05 Apr 2013 22:54:02 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UOJGH-0006qd-QV for guile-devel@gnu.org; Fri, 05 Apr 2013 22:53:56 -0400 Original-Received: from mail-ob0-x22e.google.com ([2607:f8b0:4003:c01::22e]:57946) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UOJGH-0006qQ-IP; Fri, 05 Apr 2013 22:53:49 -0400 Original-Received: by mail-ob0-f174.google.com with SMTP id wm15so1682019obc.33 for ; Fri, 05 Apr 2013 19:53:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:x-received:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; bh=MVcSUJVSp71PC/cO6pkmYYT/JnRtVjDoIMAaPaFcQi8=; b=SUBFjGNzNoMkI91chlIsdIzlvo7/U1j+0JnmebZlnsofFH6lPvXqhZ06uZhd54OKlH NGCwv+N5nIaCFwyV5sG0WL/3m8yIpVdC1qy+laZgdIA4/925tl7A88d3ohReGpjjY/Bf cBitFMgmYK/StBnCAxJtuDmP7tl6IJRo4fPYqH0YdD4kzxwlxv/jW5kV70KL5gi1al7R r1gx6izEAHqEAcDn38As4UthqxAi7hwtwY0pIjYPT8y+WqGdeZpzVyMnvZMgoD7k3bbQ OI9BCdHhYyyD7ry+p6y2Bkn1jj9RB6puh/IQ7eOAEwlGuoWr8kDAj14WthyeNp3Tm2Oe xSmg== X-Received: by 10.60.29.129 with SMTP id k1mr10094023oeh.8.1365216828244; Fri, 05 Apr 2013 19:53:48 -0700 (PDT) Original-Received: by 10.182.109.99 with HTTP; Fri, 5 Apr 2013 19:53:48 -0700 (PDT) Original-Received: by 10.182.109.99 with HTTP; Fri, 5 Apr 2013 19:53:48 -0700 (PDT) In-Reply-To: <87bo9s8opj.fsf@Kagami.home> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4003:c01::22e X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:16159 Archived-At: --e89a8ff2566816c98b04d9a850f2 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable =E5=9C=A8 2013-4-6 AM8:53=EF=BC=8C"Ian Price" = =E5=86=99=E9=81=93=EF=BC=9A > > Nala Ginrut writes: > > > +@deffn {Scheme Procedure} call/ec proc > > +'ec' stands for escape-continuation, or so-called 'one-shot' continuation. > > +@var{call/ec} is equivalent to call-with-escape-continuation. > > +A continuation obtained from call/ec is actually a kind of prompt. @var{call/ec} > > +is often an easy replacement for @var{call/cc} to improve performance. > > +More details read @uref{ http://www.cs.indiana.edu/~bruggema/one-shots-abstract.html, > > +Representing control in the presence of one-shot continuations}. > > +@end deffn > This isn't any good. It doesn't tell us what an escape continuation is, > it doesn't tell us how to use it, and it only hints at why you should > use them. Yeah, if you know what a continuation is "one-shot > continuation" isn't going to be a surprising definition, but we can do > better than that in Guile's manual. > > Here is something closer to how I envision this section should be > written. I have not taken the liberty of texinfoifying it. > > ---- > Often in Guile, you do not need the full unrestricted power of first > class continuations, you just want an escape. For example, to break > out of multiplying a list of numbers, you might write > > (define (product list) > (call-with-current-continuation > (lambda (break) > (let loop ((list list) (product 1)) > (cond ((null? list) product) > ((zero? (car list)) (break 0)) > (else (loop (cdr list) (* (car list) product)))))))) > > In this case, it can be more transparent, and more efficient, to use a > restricted form of continuation, which we refer to as an escape (or > one-shot) continuation, that only permits you to call it once from to > escape from inside the body of the function. > > > Scheme Procedure call-with-escape-continuation proc > Scheme Procedure call/ec proc > > Capture the current escape-only continuation, and call proc with this > continuation as its argument. The return value(s) of this expression > are the value(s) returned by proc, or, the arguments passed to the > escape continuation if it is invoked. > > If the escape continuation is invoked more than once, or it is invoked > after proc has returned, it is an $error. > > call/ec is an alias for call-with-escape-continuation > ---- > > I didn't check what error actually gets returned, so that bit needs > filled in. > > In various parts of the manual, we mention that prompts should be used > for the situation of escapes. We should probably hunt those down and > replace those with recommendations to use call/ec or let/ec. > > > +@deffn {Scheme Syntax} let/ec k body > > +Equivalent to (call/ec (lambda (k) body ...)). > > +@end deffn > Missing ellipses in the function prototype. In Texinfo, you should be > using @dots{} rather than three periods for ellipses. > > > +@example > > +(use-module (ice-9 control)) > > + > > +(call/ec (lambda (return) > > + (return 123))) > > + > > +(let/ec return (return 123)) > > +@end example > Not a particularly convincing example, maybe drop it? > > > + > > +(define %call/ec-prompt > > + (make-prompt-tag)) > You don't use this, so you can remove it. If your intent was to reuse > the prompt so that you didn't have to do a gensym each time, beware, > this won't give the correct semantics for call/ec. > > e.g. > (call/ec > (lambda (outer) > (call/ec > (lambda (inner) > (outer #f))) > #t)) > > will return #t rather than #f > > > +(define-syntax-rule (call/ec proc) > define rather than define-syntax-rule > > > + ;; aka. `call-with-escape-continuation' > Rather than an aka in a comment, maybe we should export this. In the > example documentation given above, I've assumed this. > > > + (let ((tag (make-prompt-tag))) > > + (call-with-prompt > > + tag > > + (lambda () > > + (proc (lambda args (apply abort-to-prompt args)))) > you are not aborting to the tag, but to the first of the args > (the dangers of copy-paste) > > > + (lambda (_ . args) > > + (apply values args))))) > > + > > +(define-syntax-rule (let/ec k e e* ...) > > + ;; aka. `let-escape-continuation' > Rather let-with-escape-continuation than let-escape-continuation, since > it's the same convention as with call/ec and call/cc (not that it > matters if we don't export it) > > As an aside, we don't have a corresponding let/cc, but I suspect most > uses of it in practice would be replaced by let/ec. > > > -(define-syntax-rule (let/ec k e e* ...) ; TODO: move to core > > - (let ((tag (make-prompt-tag))) > > - (call-with-prompt > > - tag > > - (lambda () > > - (let ((k (lambda args (apply abort-to-prompt tag args)))) > > - e e* ...)) > > - (lambda (_ res) res)))) > > - > > - > > (define %future-prompt > > ;; The prompt futures abort to when they want to wait for another > > ;; future. > This isn't the only definition of let/ec in the Guile source code. I see > definitions in module/language/tree-il/peval.scm and > module/sxml/match.scm (as an aside, I notice match.scm makes the prompt > reuse mistake you almost did) > Yes, but the original purpose is to move the "futures" one. And I apologize for the redundant things. :-( > -- > Ian Price -- shift-reset.com > > "Programming is like pinball. The reward for doing it well is > the opportunity to do it again" - from "The Wizardy Compiled" --e89a8ff2566816c98b04d9a850f2 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable


=E5=9C=A8 2013-4-6 AM8:53=EF=BC=8C"Ian Price" <ianprice90@googlemail.com>=E5=86=99=E9= =81=93=EF=BC=9A
>
> Nala Ginrut <nalaginrut@gma= il.com> writes:
>
> > +@deffn {Scheme Procedure} call/ec proc
> > +'ec' stands for escape-continuation, or so-called 'o= ne-shot' continuation.
> > +@var{call/ec} is equivalent to call-with-escape-continuation. > > +A continuation obtained from call/ec is actually a kind of promp= t. @var{call/ec}
> > +is often an easy replacement for @var{call/cc} to improve perfor= mance.
> > +More details read @uref{http://www.cs.indiana.edu/~bruggema/one-sho= ts-abstract.html,
> > +Representing control in the presence of one-shot continuations}.=
> > +@end deffn
> This isn't any good. It doesn't tell us what an escape continu= ation is,
> it doesn't tell us how to use it, and it only hints at why you sho= uld
> use them. Yeah, if you know what a continuation is "one-shot
> continuation" isn't going to be a surprising definition, but = we can do
> better than that in Guile's manual.
>
> Here is something closer to how I envision this section should be
> written. I have not taken the liberty of texinfoifying it.
>
> ----
> Often in Guile, you do not need the full unrestricted power of first > class continuations, you just want an escape. =C2=A0For example, to br= eak
> out of multiplying a list of numbers, you might write
>
> =C2=A0 (define (product list)
> =C2=A0 =C2=A0 (call-with-current-continuation
> =C2=A0 =C2=A0 =C2=A0 (lambda (break)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let loop ((list list) (product 1))
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (cond ((null? list) product)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((zero? (car l= ist)) (break 0))
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (else (loop (c= dr list) (* (car list) product))))))))
>
> In this case, it can be more transparent, and more efficient, to use a=
> restricted form of continuation, which we refer to as an escape (or > one-shot) continuation, that only permits you to call it once from to<= br> > escape from inside the body of the function.
>
>
> Scheme Procedure call-with-escape-continuation proc
> Scheme Procedure call/ec proc
>
> Capture the current escape-only continuation, and call proc with this<= br> > continuation as its argument. =C2=A0The return value(s) of this expres= sion
> are the value(s) returned by proc, or, the arguments passed to the
> escape continuation if it is invoked.
>
> If the escape continuation is invoked more than once, or it is invoked=
> after proc has returned, it is an $error.
>
> call/ec is an alias for call-with-escape-continuation
> ----
>
> I didn't check what error actually gets returned, so that bit need= s
> filled in.
>
> In various parts of the manual, we mention that prompts should be used=
> for the situation of escapes. =C2=A0We should probably hunt those down= and
> replace those with recommendations to use call/ec or let/ec.
>
> > +@deffn {Scheme Syntax} let/ec k body
> > +Equivalent to (call/ec (lambda (k) body ...)).
> > +@end deffn
> Missing ellipses in the function prototype. In Texinfo, you should be<= br> > using @dots{} rather than three periods for ellipses.
>
> > +@example
> > +(use-module (ice-9 control))
> > +
> > +(call/ec (lambda (return)
> > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (return 123)))
> > +
> > +(let/ec return (return 123))
> > +@end example
> Not a particularly convincing example, maybe drop it?
>
> > +
> > +(define %call/ec-prompt
> > + =C2=A0(make-prompt-tag))
> You don't use this, so you can remove it. =C2=A0If your intent was= to reuse
> the prompt so that you didn't have to do a gensym each time, bewar= e,
> this won't give the correct semantics for call/ec.
>
> e.g.
> (call/ec
> =C2=A0 (lambda (outer)
> =C2=A0 =C2=A0 (call/ec
> =C2=A0 =C2=A0 =C2=A0 (lambda (inner)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 (outer #f)))
> =C2=A0 =C2=A0 #t))
>
> will return #t rather than #f
>
> > +(define-syntax-rule (call/ec proc)
> define rather than define-syntax-rule
>
> > + =C2=A0;; aka. `call-with-escape-continuation'
> Rather than an aka in a comment, maybe we should export this. =C2=A0In= the
> example documentation given above, I've assumed this.
>
> > + =C2=A0(let ((tag (make-prompt-tag)))
> > + =C2=A0 =C2=A0(call-with-prompt
> > + =C2=A0 =C2=A0 tag
> > + =C2=A0 =C2=A0 (lambda ()
> > + =C2=A0 =C2=A0 =C2=A0 (proc (lambda args (apply abort-to-prompt = args))))
> you are not aborting to the tag, but to the first of the args
> (the dangers of copy-paste)
>
> > + =C2=A0 =C2=A0 (lambda (_ . args)
> > + =C2=A0 =C2=A0 =C2=A0 (apply values args)))))
> > +
> > +(define-syntax-rule (let/ec k e e* ...)
> > + =C2=A0;; aka. `let-escape-continuation'
> Rather let-with-escape-continuation than let-escape-continuation, sinc= e
> it's the same convention as with call/ec and call/cc (not that it<= br> > matters if we don't export it)
>
> As an aside, we don't have a corresponding let/cc, but I suspect m= ost
> uses of it in practice would be replaced by let/ec.
>
> > -(define-syntax-rule (let/ec k e e* ...) =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 ; TODO: move to core
> > - =C2=A0(let ((tag (make-prompt-tag)))
> > - =C2=A0 =C2=A0(call-with-prompt
> > - =C2=A0 =C2=A0 tag
> > - =C2=A0 =C2=A0 (lambda ()
> > - =C2=A0 =C2=A0 =C2=A0 (let ((k (lambda args (apply abort-to-prom= pt tag args))))
> > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 e e* ...))
> > - =C2=A0 =C2=A0 (lambda (_ res) res))))
> > -
> > -
> > =C2=A0(define %future-prompt
> > =C2=A0 =C2=A0;; The prompt futures abort to when they want to wai= t for another
> > =C2=A0 =C2=A0;; future.
> This isn't the only definition of let/ec in the Guile source code.= I see
> definitions in module/language/tree-il/peval.scm and
> module/sxml/match.scm (as an aside, I notice match.scm makes the promp= t
> reuse mistake you almost did)
>

Yes, but the original purpose is to move the "futures&q= uot; one.
And I apologize for the redundant things. :-(

> --
> Ian Price -- shift-reset.com >
> "Programming is like pinball. The reward for doing it well is
> the opportunity to do it again" - from "The Wizardy Compiled= "

--e89a8ff2566816c98b04d9a850f2--