From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Emanuel Berg via Users list for the GNU Emacs text editor Newsgroups: gmane.emacs.help Subject: Re: Closures in Emacs and their usage scenarios. Date: Thu, 30 Sep 2021 01:06:57 +0200 Message-ID: <87sfxnnfqm.fsf@zoho.eu> References: <87ilyjlxnn.fsf@logand.com> <87y27fjal0.fsf@logand.com> Reply-To: Emanuel Berg Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="33068"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) To: help-gnu-emacs@gnu.org Cancel-Lock: sha1:hwt4oewqlFdKgtejJyVFYtskyF0= Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Thu Sep 30 01:07:55 2021 Return-path: Envelope-to: geh-help-gnu-emacs@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 1mVig7-0008RK-3Q for geh-help-gnu-emacs@m.gmane-mx.org; Thu, 30 Sep 2021 01:07:55 +0200 Original-Received: from localhost ([::1]:51266 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mVig6-0000JD-0T for geh-help-gnu-emacs@m.gmane-mx.org; Wed, 29 Sep 2021 19:07:54 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:52268) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mVifR-0000J5-1q for help-gnu-emacs@gnu.org; Wed, 29 Sep 2021 19:07:14 -0400 Original-Received: from ciao.gmane.io ([116.202.254.214]:46270) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mVifO-0007vQ-TA for help-gnu-emacs@gnu.org; Wed, 29 Sep 2021 19:07:12 -0400 Original-Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1mVifM-0007W3-Vh for help-gnu-emacs@gnu.org; Thu, 30 Sep 2021 01:07:08 +0200 X-Injected-Via-Gmane: http://gmane.org/ Mail-Followup-To: help-gnu-emacs@gnu.org Mail-Copies-To: never Received-SPF: pass client-ip=116.202.254.214; envelope-from=geh-help-gnu-emacs@m.gmane-mx.org; helo=ciao.gmane.io X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.249, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "help-gnu-emacs" Xref: news.gmane.io gmane.emacs.help:133401 Archived-At: Tomas Hlavaty wrote: > In Emacs Lisp, closures mutating captured variables might be > rare now because lexical scoping arrived recently. Well, "[s]upport for lexical scoping in Emacs Lisp" came in Emacs 24.1. I don't know if you can ask Emacs when something came or when a particular version came, but that mail to info-gnu-emacs is dated 2012-06-10, so that's not yesterday. [1] It is 9y 3m 19d ago. > There are examples in the Emacs code base already, see > thunk-delay, for example. It would help to see examples of the most base use cases. One can always combine it into whatever level of complexity one desires after that ... > The toggle-counter-direction is an interesting example. I don't understand what it is supposed to show? > Next step could be showing the wonderful concept of > generators; brilliantly shown, for example, in a solution of > the same fringe problem. Once one understands this, it is > a great way of creating light weight streams on the spot. > It is also a robust solution to off-by-one errors often > caused by complexities of indexing in complex loops. Okay, can you show this? I mean the streams ... > Because closures and dynamic binding does not go together > well. Luckily, that is changing now and closures became > relevant in ELisp. Oh, no, not this again ... the counter example (not a pun), is that an example of a "shared closure" (several defuns closing it), with a "state" (what I called memory earlier) in the form of the "captured variable" `times', and that variable is "mutated" since it's value is altered with the `cl-incf', `cl-decf' and `setq' setters, while in Haskell and OCaml - which don't allow that - instead of changing the variable one would instead have to add a new one, and that wouldn't work here, since it is all based on operations targeted at ONE variable? Is that a correct interpretation of the terminology? ;;; -*- lexical-binding: t -*- ;;; ;;; this file: ;;; http://user.it.uu.se/~embe8573/emacs-init/times.el ;;; https://dataswamp.org/~incal/emacs-init/times.el (require 'cl-lib) (let ((times)) (defun times-incf (&optional x) (cl-incf times (or x 1)) ) (defun times-decf (&optional x) (cl-decf times (or x 1)) ) (defun times-reset (&optional x) (setq times (or x 0) )) (defun times-print () (insert (number-to-string times)) )) ;; (times-reset) ; 0 ;; (times-reset 100) ; 100 ;; (times-print) ; "100" ;; (times-incf) ; 101 ;; (times-incf 10) ; 111 ;; (times-decf 111) ; 0 ;; (times-decf) ; -1 So here we see a theoretical use case, which is the OO design. In practice, there are two use cases what I can see, one is the state (the persistent variable between calls) and the other is sharing data between functions. Maybe you see something more, do tell ... And, what other use cases are there? Again, keep examples as simple as possible ... >> Note also that such mutated+captured variables are more costly (at >> least in the most prevalent way to implement closures). > > [...] In any case, optimizing this is not really a high > priority issue I think. Well, if someone wants to do it it doesn't really matter what the priority is ... it's always like that BTW. [1] https://lists.gnu.org/archive/html/info-gnu-emacs/2012-06/msg00000.html -- underground experts united https://dataswamp.org/~incal