unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Andy Wingo <wingo@pobox.com>
To: Thomas Girod <girodt@gmail.com>
Cc: guile-user <guile-user@gnu.org>
Subject: Re: manipulating continuations
Date: Thu, 17 Feb 2011 12:08:56 +0100	[thread overview]
Message-ID: <m339nm535j.fsf@unquote.localdomain> (raw)
In-Reply-To: <1297887196-sup-8146@cresylol.hd.free.fr> (Thomas Girod's message of "Wed, 16 Feb 2011 21:30:07 +0100")

Hi Thomas,

Thanks for playing around with prompts!  We use them internally in
Guile, but as they are not yet a standard part of Scheme, there's less
awareness of what they're up to.

Your example brings up an interesting point:

On Wed 16 Feb 2011 21:30, Thomas Girod <girodt@gmail.com> writes:

>> (use-modules (ice-9 control))
>> (define (foo)
>>   (% (begin
>>        (display "first part\n")
>>        (abort)
>>        (display "second part\n")
>>        (abort)
>>        (display "third time\n"))
>>      (lambda (cont) cont)))
>
> scheme@(guile-user)> (foo)
> first part
> $1 = #<partial-continuation 906f5e0>
> scheme@(guile-user)> ($1)
> second part
> module/system/repl/repl.scm:98:4: In procedure with-stack-and-prompt:
> module/system/repl/repl.scm:98:4: Throw to key `vm-error' with args `(vm-run "Too few values returned to continuation" ())'.

What's happening here is that $1, the continuation returned in the first
(abort), does not itself include a prompt.

So when you invoke it again, you are running it without an enclosing
prompt -- so when the second (abort) is called, it finds the next
closest prompt with the default prompt tag (as we did not specify one
explicitly), and that prompt is part of the REPL implementation.  It so
happens that the abort handler for the REPL prompt expects at least one
value to be returned to it, via (abort FOO ...); hence this error.
(Though really we should make this error more helpful.)

Why is it implemented this way, you ask?  Well it's to preserve tail
recursion in some cases.  See the first third of the 2007 paper by
Dybvig, Peyton-Jones, and Sabry, "A monadic framework for delimited
continuations", at http://www.cs.indiana.edu/~dyb/pubs/monadicDC.pdf.
Guile's % (or call-with-prompt) corresponds to the -F- operator.

> I guess I'm having a problem very similar to the previous one I encountered,
> linked to the way prompts are built based on call/cc, right ? Are there any
> ways to solve this ?

Prompts are not actually built on call/cc; and indeed they cannot be.

So!  Your real concern was to be able to make coroutines or generators
or something, right?  Let's use a tagged prompt, and use the more
primitive call-with-prompt and abort-to-prompt procedures:

    (define (coroutine proc)
      (let ((tag (make-prompt-tag)))
        (define (yield . args)
          (apply abort-to-prompt tag args))
        (define (handler cont . args)
          (define (resume . args)
            (call-with-prompt tag
              (lambda () (apply cont args))
              handler))
          (apply values resume args))
        (call-with-prompt tag
          (lambda () (proc yield))
          handler)))

    (coroutine
      (lambda (yield)
        (display "first part\n")
        (yield)
        (display "second part\n")
        (yield)
        (display "third time\n")))
    first part
    $2 = #<procedure resume args>

    scheme@(guile-user)> ($2)
    second part
    $3 = #<procedure resume args>

    scheme@(guile-user)> ($3)
    third time

Happy hacking,

Andy
-- 
http://wingolog.org/



  parent reply	other threads:[~2011-02-17 11:08 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-12 14:10 manipulating continuations Thomas Girod
2011-02-12 15:43 ` Andy Wingo
2011-02-12 16:40   ` Keith Wright
2011-02-12 17:16     ` Andy Wingo
2011-02-12 20:56       ` Thien-Thi Nguyen
2011-02-12 21:33         ` Andy Wingo
     [not found]   ` <1297887196-sup-8146@cresylol.hd.free.fr>
2011-02-17 11:08     ` Andy Wingo [this message]
  -- strict thread matches above, loose matches on Subject: below --
2011-02-12  8:35 Tomtom

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=m339nm535j.fsf@unquote.localdomain \
    --to=wingo@pobox.com \
    --cc=girodt@gmail.com \
    --cc=guile-user@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).