From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Andy Wingo Newsgroups: gmane.lisp.guile.user Subject: Re: manipulating continuations Date: Thu, 17 Feb 2011 12:08:56 +0100 Message-ID: References: <4D5694ED.7080402@gmail.com> <1297887196-sup-8146@cresylol.hd.free.fr> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1297949231 6380 80.91.229.12 (17 Feb 2011 13:27:11 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Thu, 17 Feb 2011 13:27:11 +0000 (UTC) Cc: guile-user To: Thomas Girod Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Thu Feb 17 14:27:07 2011 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Pq3sv-0006Ea-Te for guile-user@m.gmane.org; Thu, 17 Feb 2011 14:27:06 +0100 Original-Received: from localhost ([127.0.0.1]:33825 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pq3sv-0000Mm-Bb for guile-user@m.gmane.org; Thu, 17 Feb 2011 08:27:05 -0500 Original-Received: from [140.186.70.92] (port=41068 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pq3sn-0000Hf-VA for guile-user@gnu.org; Thu, 17 Feb 2011 08:26:59 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Pq3sj-0000df-1f for guile-user@gnu.org; Thu, 17 Feb 2011 08:26:54 -0500 Original-Received: from a-pb-sasl-sd.pobox.com ([64.74.157.62]:59287 helo=sasl.smtp.pobox.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Pq3si-0000Me-U5 for guile-user@gnu.org; Thu, 17 Feb 2011 08:26:53 -0500 Original-Received: from sasl.smtp.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-sd.pobox.com (Postfix) with ESMTP id E2E1E3DCD; Thu, 17 Feb 2011 08:26:29 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=sasl; bh=hUFcb6cKY87dazFGNkw2CUlmbPo=; b=tMf8le de10gY1dmEOIaNmSCqYly0nBMOmKeuB4gevj35bqf6m9ZiQd9RlZ3IJWAS/FDEed Y338uPj8HewAi/YL7n5meFBF59KGphw4ZedJxsA2JSzOSf881Ie3cdEw4k3ioOUY DHcXi9FVaVdWTG/T4GeE64DMjU1k4tPPz40Y4= DomainKey-Signature: a=rsa-sha1; c=nofws; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=sasl; b=nIAGNkvH4/X+7toKFxd+tliAF9m6zbkN c5SY3K5JsrTxTa6dCyrq+SBpQcRJHucO0uP2Bm/4WTX27kyETQ8AFumbDcxemyoa YqlB/AzyiIdhye72zBgkmzY6VlfmbG3XVjYYfbsHmNyTWa5cRavwBAQlLwdDEdjA iGEfoM/sibM= Original-Received: from a-pb-sasl-sd.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-sd.pobox.com (Postfix) with ESMTP id CFD253DCC; Thu, 17 Feb 2011 08:26:28 -0500 (EST) Original-Received: from unquote.localdomain (unknown [90.164.198.39]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by a-pb-sasl-sd.pobox.com (Postfix) with ESMTPSA id 068193DCB; Thu, 17 Feb 2011 08:26:26 -0500 (EST) In-Reply-To: <1297887196-sup-8146@cresylol.hd.free.fr> (Thomas Girod's message of "Wed, 16 Feb 2011 21:30:07 +0100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) X-Pobox-Relay-ID: 86DC9B82-3A99-11E0-8218-AF401E47CF6F-02397024!a-pb-sasl-sd.pobox.com X-detected-operating-system: by eggs.gnu.org: Solaris 10 (beta) X-Received-From: 64.74.157.62 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:8439 Archived-At: 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 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 = # > 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 = # scheme@(guile-user)> ($2) second part $3 = # scheme@(guile-user)> ($3) third time Happy hacking, Andy -- http://wingolog.org/