From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Tomas Hlavaty Newsgroups: gmane.emacs.devel Subject: Re: continuation passing in Emacs vs. JUST-THIS-ONE Date: Wed, 12 Apr 2023 01:07:32 +0200 Message-ID: <87v8i2dnm3.fsf@logand.com> References: <87leizif4r.fsf@logand.com> <874jpmfaw9.fsf@logand.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="4161"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Jim Porter , Karthik Chikmagalur , "emacs-devel@gnu.org" To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Wed Apr 12 01:08:48 2023 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pmN6U-0000sn-Mw for ged-emacs-devel@m.gmane-mx.org; Wed, 12 Apr 2023 01:08:46 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pmN5b-0007Xd-Sv; Tue, 11 Apr 2023 19:07:51 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pmN5Z-0007XA-Pu for emacs-devel@gnu.org; Tue, 11 Apr 2023 19:07:49 -0400 Original-Received: from logand.com ([37.48.87.44]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pmN5U-0001pt-5s for emacs-devel@gnu.org; Tue, 11 Apr 2023 19:07:49 -0400 Original-Received: by logand.com (Postfix, from userid 1001) id 8B5F919E638; Wed, 12 Apr 2023 01:07:33 +0200 (CEST) X-Mailer: emacs 28.2 (via feedmail 11-beta-1 I) In-Reply-To: Received-SPF: pass client-ip=37.48.87.44; envelope-from=tom@logand.com; helo=logand.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 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-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:305253 Archived-At: On Tue 11 Apr 2023 at 16:22, Stefan Monnier wrote: >> It is useful to acknowledge, that there are 3 different use-cases: >> a) asynchronous processes >> b) threads >> c) iter > > I can't see how `iter` would be a use case for futures. It makes it easy to implement async/await without the need for asynchronous processes or threads. >> My impression was that futur.el was trying to address a) and b) but >> now you say it does address a) only. That is rather limited. > > Looking at existing code, iter and threads are virtually never used, > so from where I stand it seems to cover the 99% cases. Strange that futur.el is "primarily concerned with making it easier to write asynchronous code" but limits itself to asynchronous processes only. I am also "concerned with making it easier to write asynchronous code" but I explore various options available in Emacs so that the result would not end up with some patological flaw due to specifics of asynchronous processes. I do not know how useable threads in Emacs are at the moment, but they are already there and the examples I tried worked well. If they are not useable now, I hope they will be useable in the future. (Pun intended:-) And I do not think I am the only one: From: Po Lu Date: Mon, 03 Apr 2023 12:03:17 +0800 id:87mt3pr4sa.fsf@yahoo.com I have not looked carefully at this thread, but I would hope that if people are discussing a way to add multiprocessing to Emacs, we settle on separate threads of execution executing in parallel, with all the interlocking necessary to make that happen, like in most Unix thread implementations. It would be a shame not to consider them. Especially when that use-case is easy to implement and works as demonstrated with the promise-pipelining-server3 example. >>>> No, the iter case does map directly to futures: >>>> >>>> (await >>>> (async-iter >>>> (let ((a (async-iter >>>> (message "a1") >>>> (await-iter (sleep-iter3 3)) >>>> (message "a2") >>>> 1)) >>>> (b (async-iter >>>> (message "b1") >>>> (let ((c (async-iter >>>> (message "c1") >>>> (await-iter (sleep-iter3 3)) >>>> (message "c2") >>>> 2))) >>>> (message "b2") >>>> (+ 3 (await-iter c)))))) >>>> (+ (await-iter a) (await-iter b))))) >>> >>> I must say I don't understand this example: in which sense is it using >>> "iter"? I don't see any `iter-yield`. >> >> await-iter and async-iter macros are using iter under the hood. > > The point of `iter` is to provide something that will iterate through > a sequence of things. Here I don't see any form of iteration. I sent the whole self-contained example. The iteration happens in the top-level loop (see await-in-background). > You seem to use your `iter`s just as (expensive) thunks (futures). What do you mean? Are thunks expensive? More expensive than cl-struct and CLOS in futur.el? Surely it's the other way round. In the use-case of iter (no asynchronous processes or threads), iter is used to do cps rewriting needed by async-iter. > Maybe what you mean by "iter" is the use of CPS-translation > (implemented by `generator.el`)? Yes, iter provides the sequence of steps needed to compute the whole async-iter expression. See (iter-make (iter-yield (progn ,@body))) in async-iter macro. >>> Of course. You could do something like >>> >>> (futur-let* >>> ((a (futur-let* ((_ <- (futur-process-make >>> :command '("sleep" "9")))) >>> 9)) >>> (b (futur-let* ((_ <- (futur-process-make >>> :command '("sleep" "8")))) >>> 8)) >>> (a-val <- a) >>> (b-val <- b)) >>> (message "Result = %s" (+ a-val b-val)))) >> >> So will futur.el take 9sec or 17sec? > > 9 secs, of course: the above creates 2 futures and emits the message > when they're both done. Since those futures are executed in > subprocesses, they execute concurrently. Good. So I don't understand your remark about parallelism. Maybe I should believe you that it would take 9sec, but I would rather verify that by myself because being "executed in subprocesses" does not necessarily mean "they execute concurrently". >>> Similarly the "intended return value" of a process will depend on what >>> the process does. In some cases it will be the stdout, but I see no >>> reason to restrict my fundamental function to such a choice. >> This overgeneralized thinking is beyond usefulness and harmfully leads >> to the problem of how to maintain state. > > While I do like to over-generalize, in this case, there is no > generalization involved. The code is the simple result of a thin > wrapper around the existing `make-process` to make it obey the > `futur.el` API. So if it's overgeneralized, it's not my fault, it's > `make-process`s :-) Not really, make-process is general because it covers many use-cases. Futures are quite specific. Anything beyond the specifics cause issues.