From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: Delimited continuations Date: Mon, 11 Dec 2017 11:47:01 -0500 Message-ID: References: <87r2s2cyoj.fsf@web.de> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: blaine.gmane.org 1513010889 26914 195.159.176.226 (11 Dec 2017 16:48:09 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 11 Dec 2017 16:48:09 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Dec 11 17:48:06 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eORFI-0006h5-Ub for ged-emacs-devel@m.gmane.org; Mon, 11 Dec 2017 17:48:01 +0100 Original-Received: from localhost ([::1]:54412 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eORFQ-0003WB-0X for ged-emacs-devel@m.gmane.org; Mon, 11 Dec 2017 11:48:08 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:59390) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eOREZ-0003Rr-9d for emacs-devel@gnu.org; Mon, 11 Dec 2017 11:47:16 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eOREW-0005GF-Mk for emacs-devel@gnu.org; Mon, 11 Dec 2017 11:47:15 -0500 Original-Received: from [195.159.176.226] (port=45192 helo=blaine.gmane.org) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eOREW-0005Ff-GA for emacs-devel@gnu.org; Mon, 11 Dec 2017 11:47:12 -0500 Original-Received: from list by blaine.gmane.org with local (Exim 4.84_2) (envelope-from ) id 1eOREL-0004Qg-BE for emacs-devel@gnu.org; Mon, 11 Dec 2017 17:47:01 +0100 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 53 Original-X-Complaints-To: usenet@blaine.gmane.org Cancel-Lock: sha1:mCAoTh+hnL+GmQgMZHgVQo1tg3s= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 195.159.176.226 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:220889 Archived-At: [ For some reason, while I had no trouble getting an intuitive understanding of continuations and can happily write and reason about CPS style code, I must admit that I still haven't managed to really wrap my head around delimited continuations. You've been warned. ] > (reset (lambda (p) > (+ (+ 1 2) > (shift p (lambda (k) (funcall k 1)))))) [...] > (+ 1 2) is executed twice. I think this isn't necessarily so? Right, but since (+ 1 2) is pure the problem is minor (and also because whether (+ 1 2) was already computed or not depends on evaluation order of arguments, which is defined in Elisp but would still be within the scope of "acceptable quirks" in my book if it's not 100% obeyed). Things get more interesting with side-effects: (defvar fwdc nil) (reset (λ (p) (if fwdl 3 (setq fwdc t) (shift p (λ (k) (k 5)))))) since we end up re-computing the `if` test and hence not using the `5` provided to `k`. I think this case is a clear "bug" (because, IIUC, (shift _ (λ (k) (k v))) should be equivalent to just `v`). BTW, John: > (defun shift (k entry) > (if (eq (nth 0 k) 'outer) > (throw (nth 1 k) > (funcall entry #'(lambda (val) > (funcall (nth 2 k) > (list 'inner val))))) > (nth 1 k))) It means that `entry` is evaluated within the dynamic context of `shift` rather than within the dynamic context of `reset` (because you call `entry` before calling `throw`). This has a clear downside: we use extra stack space during evaluation of `entry` (the extra stack space is equal to the stack space used between `reset` and `shift`). But I guess this is not too terrible. It also means that dynamic-bindings (and other unwind-protects such as with-current-buffer) applied within `k` up to now will still be active during evaluation of `entry`. Whether that's The Right Thing or not is a good question but is beyond what my poor brain can take right now. Stefan