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 --]
next prev parent 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).