unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Nala Ginrut <nalaginrut@gmail.com>
To: Ian Price <ianprice90@googlemail.com>
Cc: "Ludovic Courtès" <ludo@gnu.org>, guile-devel <guile-devel@gnu.org>
Subject: Re: [PATCH] Move let/ec to top-level
Date: Sat, 6 Apr 2013 10:53:48 +0800	[thread overview]
Message-ID: <CAPjoZoceqnoqWfjqyq-Uq2adzB9ZrZvRfO6iu2A68C+Lnr1w0A@mail.gmail.com> (raw)
In-Reply-To: <87bo9s8opj.fsf@Kagami.home>

[-- Attachment #1: Type: text/plain, Size: 5654 bytes --]

在 2013-4-6 AM8:53,"Ian Price" <ianprice90@googlemail.com>写道:
>
> Nala Ginrut <nalaginrut@gmail.com> 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"

[-- Attachment #2: Type: text/html, Size: 7290 bytes --]

  reply	other threads:[~2013-04-06  2:53 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-14 15:20 [PATCH] Move let/ec to top-level Nala Ginrut
2013-01-22 11:43 ` Andy Wingo
2013-03-27 21:14 ` Ludovic Courtès
2013-04-04  6:19   ` Nala Ginrut
2013-04-05 20:59     ` Ludovic Courtès
2013-04-06  0:52     ` Ian Price
2013-04-06  2:53       ` Nala Ginrut [this message]
2013-04-06  1:04     ` Ian Price
2013-04-06 13:38       ` Ludovic Courtès
2013-04-06  2:15     ` Ian Price
2013-04-06 13:41       ` Ludovic Courtès

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

  List information: https://www.gnu.org/software/guile/

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

  git send-email \
    --in-reply-to=CAPjoZoceqnoqWfjqyq-Uq2adzB9ZrZvRfO6iu2A68C+Lnr1w0A@mail.gmail.com \
    --to=nalaginrut@gmail.com \
    --cc=guile-devel@gnu.org \
    --cc=ianprice90@googlemail.com \
    --cc=ludo@gnu.org \
    /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.
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).