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: thunk.el: Document that thunk-force == funcall? Date: Thu, 19 Nov 2020 19:14:45 +0100 Message-ID: <87lfexrz6y.fsf@logand.com> References: <871rgs3tdx.fsf@web.de> <87ima21d1k.fsf@logand.com> <87d00a1c4i.fsf@logand.com> <8E031B6C-8BF3-48DC-B183-8FAF2D366408@acm.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="36469"; mail-complaints-to="usenet@ciao.gmane.io" To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Thu Nov 19 19:15:44 2020 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 1kfoTA-0009NL-0l for ged-emacs-devel@m.gmane-mx.org; Thu, 19 Nov 2020 19:15:44 +0100 Original-Received: from localhost ([::1]:51336 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kfoT8-0000iG-Vs for ged-emacs-devel@m.gmane-mx.org; Thu, 19 Nov 2020 13:15:43 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:54530) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kfoSJ-0000B8-SL for emacs-devel@gnu.org; Thu, 19 Nov 2020 13:14:51 -0500 Original-Received: from logand.com ([37.48.87.44]:38728) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kfoSH-0007u7-SL for emacs-devel@gnu.org; Thu, 19 Nov 2020 13:14:51 -0500 Original-Received: by logand.com (Postfix, from userid 1001) id 07E451A9F4C; Thu, 19 Nov 2020 19:14:48 +0100 (CET) X-Mailer: emacs 26.3 (via feedmail 11-beta-1 I) In-Reply-To: <8E031B6C-8BF3-48DC-B183-8FAF2D366408@acm.org> 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.23 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" Xref: news.gmane.io gmane.emacs.devel:259446 Archived-At: On Thu 19 Nov 2020 at 12:50, Mattias Engdeg=C3=A5rd wrot= e: > 19 nov. 2020 kl. 00.25 skrev Tomas Hlavaty : > >> interesting drawback of thunk.el implementation is that thunk-delay does >> not allow that and whatever is captured stays captured even after >> thunk-force. > > Not after byte-compilation. The interpreter is very conservative when > creating closures but the compiler makes more of an effort to capture > only variables actually used. this has nothing to do with an effort to capture only variables actually used the problem is that current implementation of thunk-delay has memory leak built-in by design and does not release captured values. those are captured in the lambda due to ,@body and references to these captured values are never released. it is not even possible to explicitly release those values because it is not known what exactly is captured. (let ((huge-data (make-list (expt 2 60)))) (setq delayed (thunk-delay (count huge-data))) ;; huge-data captured by delayed, needed to compute the delayed value (thunk-force delayed)) (garbage-collect) ;; huge-data still captured by delayed even though it is not needed anymore this is bug in thunk-delay having garbage collection does not eliminate memory leaks fix would separate thunk and memoization and release the thunk when not needed anymore: (let ((void (list nil))) (defun memoize (thunk) (let ((z void)) (lambda () (when (eq z void) (setq z (funcall thunk) thunk nil)) z)))) (defmacro thunk-delay (&rest body) `(memoize (lambda () ,@body))) at that point thunk-delay is pretty much redundant and it is better not to pretend that thunk is thunk+memoization and just teach people what thunk really is (it is just a lambda with zero arguments) minor note: the example in thunk.el would then also work in buffers without lexical-binding enabled