From unknown Sat Aug 16 19:18:38 2025 X-Loop: help-debbugs@gnu.org Subject: bug#59576: 29.0.50; named-let doesn't support dynamic binding Resent-From: Tom Levy Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 25 Nov 2022 16:56:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 59576 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: 59576@debbugs.gnu.org X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.166939532428300 (code B ref -1); Fri, 25 Nov 2022 16:56:02 +0000 Received: (at submit) by debbugs.gnu.org; 25 Nov 2022 16:55:24 +0000 Received: from localhost ([127.0.0.1]:37045 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oybz1-0007MO-RE for submit@debbugs.gnu.org; Fri, 25 Nov 2022 11:55:24 -0500 Received: from lists.gnu.org ([209.51.188.17]:58144) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oybz0-0007MG-Cy for submit@debbugs.gnu.org; Fri, 25 Nov 2022 11:55:22 -0500 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 1oybyy-0001Xt-Ty for bug-gnu-emacs@gnu.org; Fri, 25 Nov 2022 11:55:21 -0500 Received: from [145.40.109.133] (helo=145.40.109.133) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oybyx-0008QG-07 for bug-gnu-emacs@gnu.org; Fri, 25 Nov 2022 11:55:20 -0500 Received: from root by 145.40.109.133 with local (Exim 4.94.2) (envelope-from ) id 1oybec-0001tP-MU for bug-gnu-emacs@gnu.org; Fri, 25 Nov 2022 16:34:18 +0000 From: Tom Levy Message-Id: Date: Fri, 25 Nov 2022 16:34:18 +0000 X-Host-Lookup-Failed: Reverse DNS lookup failed for 145.40.109.133 (failed) Received-SPF: none client-ip=145.40.109.133; envelope-from=root@145.40.109.133; helo=145.40.109.133 X-Spam_score_int: 36 X-Spam_score: 3.6 X-Spam_bar: +++ X-Spam_report: (3.6 / 5.0 requ) BAYES_00=-1.9, DKIM_ADSP_CUSTOM_MED=0.001, FORGED_GMAIL_RCVD=1, FREEMAIL_FORGED_FROMDOMAIN=0.243, FREEMAIL_FROM=0.001, FSL_HELO_BARE_IP_1=2.347, HEADER_FROM_DIFFERENT_DOMAINS=0.25, NML_ADSP_CUSTOM_MED=0.9, NO_DNS_FOR_FROM=0.001, RDNS_NONE=0.793, SPF_NONE=0.001, SPOOFED_FREEMAIL=0.001, SPOOFED_FREEMAIL_NO_RDNS=0.001, SPOOF_GMAIL_MID=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Is `named-let' supposed to work when dynamic binding is used (as opposed to lexical binding)? Because if so, it is broken when the recursion is not in tail position. Example: ``` (eval '(named-let f ((x 10)) (if (= 0 x) 0 (1+ (f (1- x))))) ; note: recursion is *not* in tail position nil) ; change to t to enable lexical binding (makes the code work) ``` Output: ``` Debugger entered--Lisp error: (void-variable --cl-f--) (funcall --cl-f-- (1- x)) (1+ (funcall --cl-f-- (1- x))) (if (= 0 x) t (1+ (funcall --cl-f-- (1- x)))) (lambda (x) (if (= 0 x) t (1+ (funcall --cl-f-- (1- x)))))(10) funcall((lambda (x) (if (= 0 x) t (1+ (funcall --cl-f-- (1- x))))) 10) (named-let f ((x 10)) (if (= 0 x) t (1+ (f (1- x))))) eval((named-let f ((x 10)) (if (= 0 x) t (1+ (f (1- x))))) nil) (progn (eval '(named-let f ((x 10)) (if (= 0 x) t (1+ (f (1- x))))) nil)) eval((progn (eval '(named-let f ((x 10)) (if (= 0 x) t (1+ (f ...)))) nil)) t) elisp--eval-last-sexp(nil) eval-last-sexp(nil) funcall-interactively(eval-last-sexp nil) call-interactively(eval-last-sexp nil nil) command-execute(eval-last-sexp) ``` There is an easy fix. Currently `named-let' is defined as follows: ``` (defmacro named-let (name bindings &rest body) ;; ... (require 'cl-lib) (let ((fargs (mapcar (lambda (b) (if (consp b) (car b) b)) bindings)) (aargs (mapcar (lambda (b) (if (consp b) (cadr b))) bindings))) ;; According to the Scheme semantics of named let, `name' is not in scope ;; while evaluating the expressions in `bindings', and for this reason, the ;; "initial" function call below needs to be outside of the `cl-labels'. ;; When the "self-tco" eliminates all recursive calls, the `cl-labels' ;; expands to a lambda which the byte-compiler then combines with the ;; funcall to make a `let' so we end up with a plain `while' loop and no ;; remaining `lambda' at all. `(funcall (cl-labels ((,name ,fargs . ,body)) #',name) . ,aargs))) ``` I believe the issue is with the following construct: (funcall (cl-labels ((,name ...)) #',name) ...) The `funcall' to the lambda happens outside the scope of `cl-labels'. As stated in the documentation of `cl-labels', closure capture only works when lexical binding is in used. So any non-optimised recursive calls in the body will fail, because `name' is not captured. The easy fix is to move the `funcall' inside the scope of cl-labels. However the bindings must be evaluated outside the `cl-labels' (as explained in the existing comment). This can be achieved using a simple `let' outside the `cl-labels'. (This actually simplifies the code, because the bindings can be passed directly to `let' and the variable `aargs' can be eliminated.) Note that the generated bytecode with this fix is slightly different: it looks like, when all recursive calls are in tail position, this fix prevents the byte-compiler from inlining the outer function call. I am not sure if that's a significant problem. I included an example with disassembly below. (I am not including a patch because I haven't completed the copyright assignment process yet.) Cheers, Tom ------------ Disassembly example: ``` (let ((lexical-binding t)) (disassemble (byte-compile '(named-let f ((x 100000)) (if (= 0 x) 0 (f (1- x))))))) ; note: here recursion *is* in tail position ``` Output with current `named-let' implementation: ``` byte code: args: nil 0 constant 100000 1 constant nil 2:1 stack-ref 1 3 dup 4 constant 0 5 eqlsign 6 goto-if-nil 2 9 constant 0 10 stack-set 2 12 constant nil 13 goto 3 16:2 stack-ref 2 17 sub1 18 stack-set 3 20 constant :recurse 21:3 stack-set 1 23 goto-if-not-nil 1 26 return ``` Output with my proposed fix: ``` byte code: args: nil 0 constant doc: ... args: (arg1) 0 constant nil 1:1 stack-ref 1 2 dup 3 constant 0 4 eqlsign 5 goto-if-nil 2 8 constant 0 9 stack-set 2 11 constant nil 12 goto 3 15:2 stack-ref 2 16 sub1 17 stack-set 3 19 constant :recurse 20:3 stack-set 1 22 goto-if-not-nil 1 25 return 1 dup 2 constant 100000 3 call 1 4 return ``` And here is a minimal example showing that the byte-compile is unable to inline a `funcall' to a `let'-bound function: ``` (let ((lexical-binding t)) (disassemble (byte-compile '(let ((f #'(lambda (x) (message "%S" x)))) (funcall f 100000))))) ;; call to f is not inlined (let ((lexical-binding t)) (disassemble (byte-compile '(funcall #'(lambda (x) (message "%S" x)) 100000)))) ;; call to lambda is inlined ``` ------------ In GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu) of 2022-11-25 built on ... Repository revision: af545234314601ba3dcd8bf32e0d9b46e1917f79 Repository branch: master From unknown Sat Aug 16 19:18:38 2025 X-Loop: help-debbugs@gnu.org Subject: bug#59576: 29.0.50; named-let doesn't support dynamic binding References: In-Reply-To: Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 26 Nov 2022 09:50:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 59576 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Tom Levy Cc: Stefan Monnier , 59576@debbugs.gnu.org Received: via spool by 59576-submit@debbugs.gnu.org id=B59576.166945615313159 (code B ref 59576); Sat, 26 Nov 2022 09:50:01 +0000 Received: (at 59576) by debbugs.gnu.org; 26 Nov 2022 09:49:13 +0000 Received: from localhost ([127.0.0.1]:37853 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oyro9-0003QA-GZ for submit@debbugs.gnu.org; Sat, 26 Nov 2022 04:49:13 -0500 Received: from mail1456c50.megamailservers.eu ([91.136.14.56]:53592 helo=mail266c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oyro6-0003Pv-Pg for 59576@debbugs.gnu.org; Sat, 26 Nov 2022 04:49:12 -0500 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1669456143; bh=VKWZi7LFpW0Bbl+IZ9NMrYZVYUjw9WxVi9UvQ+dIooU=; h=From:Subject:Date:Cc:To:From; b=Lm2rnFyz1WPpvyoOSr1h10cRy9JAy5hN1Q7sRxNYCjQ9Fiwxhj0td+B2g7s0JiFuJ DOJ0v/3yBhCRq0OidHz3TibbFTrTe+pLwWc/vXyLTZqg3Cn3q9rDTBXIV3FNN5QXOy fli33yLwLx4sVVvBs/FhWlkw6dgN3wROb8yxkyHE= Feedback-ID: mattiase@acm.or Received: from smtpclient.apple (c188-150-171-209.bredband.tele2.se [188.150.171.209]) (authenticated bits=0) by mail266c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 2AQ9mwai127283; Sat, 26 Nov 2022 09:49:00 +0000 From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.120.0.1.13\)) Message-Id: <8DE91C19-0401-4448-82E6-64AA96C677CE@acm.org> Date: Sat, 26 Nov 2022 10:48:54 +0100 X-Mailer: Apple Mail (2.3654.120.0.1.13) X-CTCH-RefID: str=0001.0A782F28.6381E10F.004E, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Rules: X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-Origin-Country: SE X-Spam-Score: 0.3 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) `named-let` being a looping construct, it makes little sense to use it = in dynamic binding where TCO opportunities are severely limited. Ideally = we should just signal an error if an attempt to use it in dynbound code = is made. Users will thank us for that (at least they should, if they = have any sense). Second-best would be to inhibit all TCO in dynbound code but whom would = that really benefit? (Regarding your proposal, generating worse code in lexbind mode isn't a = wonderful outcome.) From unknown Sat Aug 16 19:18:38 2025 X-Loop: help-debbugs@gnu.org Subject: bug#59576: 29.0.50; named-let doesn't support dynamic binding Resent-From: Tom Levy Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 26 Nov 2022 10:37:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 59576 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Stefan Monnier , 59576@debbugs.gnu.org Received: via spool by 59576-submit@debbugs.gnu.org id=B59576.166945901517880 (code B ref 59576); Sat, 26 Nov 2022 10:37:02 +0000 Received: (at 59576) by debbugs.gnu.org; 26 Nov 2022 10:36:55 +0000 Received: from localhost ([127.0.0.1]:37917 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oysYI-0004eK-Kr for submit@debbugs.gnu.org; Sat, 26 Nov 2022 05:36:54 -0500 Received: from mail-oi1-f175.google.com ([209.85.167.175]:37642) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oysYG-0004e6-H8 for 59576@debbugs.gnu.org; Sat, 26 Nov 2022 05:36:53 -0500 Received: by mail-oi1-f175.google.com with SMTP id v82so6819482oib.4 for <59576@debbugs.gnu.org>; Sat, 26 Nov 2022 02:36:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=D9ZtBWI3d3IYdj/XvTauvUEwPkdc6j71J7B828tKEso=; b=gAqPi8OJ25+g8CPW/qZCCt2SWUEGvuc0TMGwufSoOCoGLFKXB+7bb/l7Jc8ksAwtT8 QUE6pruzc3d0VLIWKfypip0a8yMMojiW8khxL9Mn3OKH0zGr+0yfHp5/K2gXdWNe+Ql6 W7RohHZF5+2w7WLHFko9oaDW53eKj190jl4FvfPQ7twl7Kzi6IEGwNiF2kPGrtPX+uVV NLZjZm02eGhhr4XO7KdFKDLJjGhYZct/vhUROi95dJ86FMH1NOXvBT5Xw26yzW9vbzA1 86he7ZFi7znPmEmLKFjpJ7hQK/+VmWg/E7VqGeZRwJ858znIPuBomAT302eSJK8M9oCR HufA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=D9ZtBWI3d3IYdj/XvTauvUEwPkdc6j71J7B828tKEso=; b=EfjxnlVpvI19Ug4cL4jtZ4b/tR4ISBaK0rVxg7U6tmZ+wvfbJ1TvlZIgMNwJQNXqj5 dqdT1jwvkw0CjeI2lIDTl5Y1IHxxQ96uy7KNmHeL2tpYbyuGPu1GhgB0Cf5vx6LHgtbR PvsGISRvOIgWWCZp4i+7S9ni+X827nKEioBzZ5F+P2IQbnPJBI0To+Oangs92W7nsdmb SZr0AiDOZcakVaWvyoRkylpPpuPxK0SzeyhHev/7jBOPZLi1V5cUX+KIKp81sJHcpwC3 /FRtUrDmbaQxsnym4nOk+ob4FnkpJnaMQE3apWzWCWCydIXzpEMBahr3SqnrtocmXChe qTsQ== X-Gm-Message-State: ANoB5pnmdF+ort743rg2BLZRIrptimOorEe3qUS4ckBpKH88Hsux8APA nSkp+bG+MujTKRGQlJAlunZl5WLpnJvz199m/To= X-Google-Smtp-Source: AA0mqf5q3yWUoErPiwp0zezvrfrIm6YSzeczpmgWkRe67qNSq8KVolYRR87ZumWGfgTIDdMvA3eqQBzGNuCIInpiQS8= X-Received: by 2002:aca:de43:0:b0:35a:7461:8670 with SMTP id v64-20020acade43000000b0035a74618670mr10459180oig.76.1669459006765; Sat, 26 Nov 2022 02:36:46 -0800 (PST) MIME-Version: 1.0 References: <8DE91C19-0401-4448-82E6-64AA96C677CE@acm.org> In-Reply-To: <8DE91C19-0401-4448-82E6-64AA96C677CE@acm.org> From: Tom Levy Date: Sat, 26 Nov 2022 23:36:10 +1300 Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.2 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.8 (/) Personally I'm fine with `named-let' signalling an error in dynamic binding mode. (Regarding worse code in lexical binding mode: There are workarounds. An ugly one is to include both versions of `named-let' and switch between them depending on the binding mode. Another solution is to teach the byte-compiler to inline funcalls to let-bound lambdas; that's more elegant and might also benefit other code, but I have no idea how difficult it would be to implement.) On Sat, 26 Nov 2022 at 22:49, Mattias Engdeg=C3=A5rd wro= te: > > `named-let` being a looping construct, it makes little sense to use it in= dynamic binding where TCO opportunities are severely limited. Ideally we s= hould just signal an error if an attempt to use it in dynbound code is made= . Users will thank us for that (at least they should, if they have any sens= e). > > Second-best would be to inhibit all TCO in dynbound code but whom would t= hat really benefit? > > (Regarding your proposal, generating worse code in lexbind mode isn't a w= onderful outcome.) > From unknown Sat Aug 16 19:18:38 2025 X-Loop: help-debbugs@gnu.org Subject: bug#59576: 29.0.50; named-let doesn't support dynamic binding Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 26 Nov 2022 17:46:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 59576 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Tom Levy , 59576@debbugs.gnu.org Received: via spool by 59576-submit@debbugs.gnu.org id=B59576.166948475311906 (code B ref 59576); Sat, 26 Nov 2022 17:46:01 +0000 Received: (at 59576) by debbugs.gnu.org; 26 Nov 2022 17:45:53 +0000 Received: from localhost ([127.0.0.1]:41379 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oyzFQ-00035y-Pu for submit@debbugs.gnu.org; Sat, 26 Nov 2022 12:45:53 -0500 Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:22100) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oyzFO-00035r-Qv for 59576@debbugs.gnu.org; Sat, 26 Nov 2022 12:45:51 -0500 Received: from pmg3.iro.umontreal.ca (localhost [127.0.0.1]) by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id 54800440FFE; Sat, 26 Nov 2022 12:45:45 -0500 (EST) Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id 11D61440F3A; Sat, 26 Nov 2022 12:45:44 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1669484744; bh=RDW+cjsm9728ZVqKAw4qWmZjD7D5gp+23D6VJMX/Kwg=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=VDg9KBtpTFCTYa0Ampi7LWkpmFdvwQyl7emIshoqtjwxGECo2NCgRJc/G3XZVMyTE zRa0OA3G5oOvtVYw1LCsY+KUcYe8ktA3CaUHhWac39tp0p2dusXYDHFVeJetSyO7Oo h2g7WQ4EB3hz5Mnr4whYHZPmU+GBxYwH7SbejOnALhUhYp+1vD9HimCF7fdaGAYGKV aD56w1+K7UgZoQD+uON43xJ7aEpTVhRtUH6BRho+8wZ3OpyEyz03GFVWQOvIL+O3Fv KBrWhxwD8GczCELn/FSaGwrLkkOuP0lWo9jL3c8tmCCC3CcLifSnZINTNXdjPIYnD2 JOYRtW8Huwngg== Received: from pastel (unknown [104.247.241.157]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id CF404120776; Sat, 26 Nov 2022 12:45:43 -0500 (EST) From: Stefan Monnier In-Reply-To: <8DE91C19-0401-4448-82E6-64AA96C677CE@acm.org> ("Mattias =?UTF-8?Q?Engdeg=C3=A5rd?="'s message of "Sat, 26 Nov 2022 10:48:54 +0100") Message-ID: References: <8DE91C19-0401-4448-82E6-64AA96C677CE@acm.org> Date: Sat, 26 Nov 2022 12:45:40 -0500 User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-SPAM-INFO: Spam detection results: 0 ALL_TRUSTED -1 Passed through trusted hosts only via SMTP AWL -0.168 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain X-SPAM-LEVEL: X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > `named-let` being a looping construct, it makes little sense to use it in > dynamic binding where TCO opportunities are severely limited. Ideally we > should just signal an error if an attempt to use it in dynbound code is > made. Users will thank us for that (at least they should, if they have any > sense). Indeed, I'm surprised I didn't put something akin to (cl-assert lexical-binding) in that macro. It was an oversight. Stefan From debbugs-submit-bounces@debbugs.gnu.org Thu Dec 01 08:25:11 2022 Received: (at control) by debbugs.gnu.org; 1 Dec 2022 13:25:11 +0000 Received: from localhost ([127.0.0.1]:39680 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p0jYs-0002zt-R4 for submit@debbugs.gnu.org; Thu, 01 Dec 2022 08:25:11 -0500 Received: from mail-ot1-f43.google.com ([209.85.210.43]:44880) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p0jYq-0002zl-Uz for control@debbugs.gnu.org; Thu, 01 Dec 2022 08:25:09 -0500 Received: by mail-ot1-f43.google.com with SMTP id p8-20020a056830130800b0066bb73cf3bcso915659otq.11 for ; Thu, 01 Dec 2022 05:25:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=to:subject:message-id:date:mime-version:from:from:to:cc:subject :date:message-id:reply-to; bh=TqalvVEyt1dhL3HncmAt5A8WMVssXhVUxSOanrMltLI=; b=Y3tm799ZDf9sy2WZjDWlEWxUPyzVzUg5bZLHtZRsWmSmnmqlyL4TMcWspCjTUlysF5 nAL5jSWKIxrUitfffmKAPUirbwk22W/V4BaVgkftqMZTy0GqJRxVPxrxIpd81NqT4s55 OMaGKPAeTBZEhojmoNRuewbq0aKgKtESqWjwWvXlk2r7WfUSx88ISFCF34Al/QbziweV usS9iVgbebQ3MVyFrQSMVN+EQTdqMDrnxwUEM1p5KgqqMywtlnPYzUjmJJmAn7AtMzPh fD1kOb3Xu6BlOP98LXbOtaGfcT7v6uVUlKTwEra0baSIQq5hXG0uupkkA/B61a1wMhFI NLpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=to:subject:message-id:date:mime-version:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=TqalvVEyt1dhL3HncmAt5A8WMVssXhVUxSOanrMltLI=; b=O65lRAMdD8K28g1qgfI5D2J8OxpWAdmFGm7XPX5o0U+RGEN44YOlZ5qljSC5LTB9P/ m5UKhUS8a8jKprn2tLbka1ljZwisl5okLLDdz7z6i7T9wGOJ6c52o+a6A3n8X71j+8B1 udUFZw8bHyQ0LTGWBHQ/JswT+nX5mU9u+DgYgnUCdZhei88WHPQ6eAZ94D4Sis1oCc0Y wHP3p0wKuf4iKWnWHBI4VySv52UMhSvKZu81ytny//j2Mrbr/uG8RIbZ2ybJh6bRJtQS f28R+tWidt2Jxuurh/fkwd/oa0BqXl/KURN8hk9JqdSdgtammYMakPcmoHh8DFfYcVKM GYgQ== X-Gm-Message-State: ANoB5pnRk7Eoy0YCjwIRqE9SHms5c1GKNxahLNh+5WoRIq+z+0NlaKC8 Gxx7PUBc/iX4DIstDCHWZ6KtM2n+nOqr6w/Z9VJElHyV X-Google-Smtp-Source: AA0mqf6pyH8zL7UINNfnFJ2NpXbdMphEZQyI8EFXlF3bNHMeRKpG8ouNstpbshaKVVL9i3+fjWw+/XCliTX7Pqv/3eI= X-Received: by 2002:a9d:5c81:0:b0:661:c48b:12db with SMTP id a1-20020a9d5c81000000b00661c48b12dbmr23839689oti.105.1669901103282; Thu, 01 Dec 2022 05:25:03 -0800 (PST) Received: from 753933720722 named unknown by gmailapi.google.com with HTTPREST; Thu, 1 Dec 2022 05:25:02 -0800 From: Stefan Kangas X-Hashcash: 1:20:221201:control@debbugs.gnu.org::0dIDtqy0yrVW1+Ru:0cYJ MIME-Version: 1.0 Date: Thu, 1 Dec 2022 05:25:02 -0800 Message-ID: Subject: control message for bug #59576 To: control@debbugs.gnu.org Content-Type: text/plain; charset="UTF-8" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) severity 59576 wishlist quit From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 02 19:59:34 2022 Received: (at control) by debbugs.gnu.org; 3 Dec 2022 00:59:34 +0000 Received: from localhost ([127.0.0.1]:49914 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p1GsQ-0005vB-Ca for submit@debbugs.gnu.org; Fri, 02 Dec 2022 19:59:34 -0500 Received: from mail-ot1-f50.google.com ([209.85.210.50]:43707) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p1GsN-0005v4-MV for control@debbugs.gnu.org; Fri, 02 Dec 2022 19:59:32 -0500 Received: by mail-ot1-f50.google.com with SMTP id t19-20020a9d7753000000b0066d77a3d474so3929429otl.10 for ; Fri, 02 Dec 2022 16:59:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=to:subject:message-id:date:mime-version:from:from:to:cc:subject :date:message-id:reply-to; bh=/6wqsCqx3Dd0IMOwg68RDssjod1EcnGyYxEP1x6y3KQ=; b=g5Z5xfVcCKyVOL5UIkV4l+VEw+GYVb1vN4z/1k/TcTc57G98R05LQGXy8W6jr25lBc ICa43kXZhh+4Bk9xycVOheXzcVHvkkXIJGiIj7+8uAbeWZRTL3WNYoX08Kyd2ZHnZcM3 qcEScFDjRE+CH4ss5bkDKUV39uSX8qkB8lozIQ9TzFksoZyf2jkmjZFHvSLsfpSDebHu vGM+pOZl/lP1+b2hub4ioTI64rRutVMTHy3xhY6gz/rT/5ECH/YE/tTFYRcr5Ay/Oqo/ 0zMrzYKuS/f9RZuSj7L0nwzITZglx+5zVK6TkZoKEr3JJUpuRUxEQ5mUh04q8FsXVlnE /FiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=to:subject:message-id:date:mime-version:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=/6wqsCqx3Dd0IMOwg68RDssjod1EcnGyYxEP1x6y3KQ=; b=TXWkgXbRvxGNeCPRAdFWgGT6G3ic6ERVEEJMB9r/1uoNULxmT8LfjlYMg1sX7C+CZw KIdvfDRlfRy860SN+rNss3i+PLCX6k46Db4VPqx6kZ6sH3ohVX5gzjAZGCIzmKSRkr6y s/Z6uG0BcvykrnPG5S3kNcfCDKoN2iYlunjSJvYKDP8qMyn28ndgh99wpnLoIPC7HQI9 rtIPKQkW1ifLB86UtynkxSDxVgm0yeN8J71jDViaNe6u7fzPkcV0mkjr9EWyaQJmw47q H0fn/HZGl5ZxuYwapYVan0vFd7Ab7/iQ/1d6LOrnvAJ8Ed3POtdjYMg0sDKa/w36b0gh QnWA== X-Gm-Message-State: ANoB5pmLV+4274LEFc83E8BisSxPPo7xIgBttQQWdPyMIdTFSU0CbAox 3gldrJhVrabP0eIjzb4Dxc+Q86txbJlWTogK9ky3JDQT X-Google-Smtp-Source: AA0mqf4iQbVRw8rVJJGsG9gxn9J9FyBRSERV6XB8KrjZ4RJHHzFMpKf1hHbUDYG5KpZirA6ojsyZuvXSJfhvsa88Tv0= X-Received: by 2002:a05:6830:11cd:b0:66e:7741:ed1d with SMTP id v13-20020a05683011cd00b0066e7741ed1dmr441363otq.224.1670029166028; Fri, 02 Dec 2022 16:59:26 -0800 (PST) Received: from 753933720722 named unknown by gmailapi.google.com with HTTPREST; Fri, 2 Dec 2022 16:59:25 -0800 From: Stefan Kangas X-Hashcash: 1:20:221203:control@debbugs.gnu.org::xgHR57I5+QbfdnR3:3fBp MIME-Version: 1.0 Date: Fri, 2 Dec 2022 16:59:25 -0800 Message-ID: Subject: control message for bug #59576 To: control@debbugs.gnu.org Content-Type: text/plain; charset="UTF-8" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) tags 59576 + wontfix quit From unknown Sat Aug 16 19:18:38 2025 MIME-Version: 1.0 X-Mailer: MIME-tools 5.505 (Entity 5.505) X-Loop: help-debbugs@gnu.org From: help-debbugs@gnu.org (GNU bug Tracking System) To: Tom Levy Subject: bug#59576: closed (Re: bug#59576: 29.0.50; named-let doesn't support dynamic binding) Message-ID: References: X-Gnu-PR-Message: they-closed 59576 X-Gnu-PR-Package: emacs X-Gnu-PR-Keywords: wontfix Reply-To: 59576@debbugs.gnu.org Date: Mon, 21 Aug 2023 12:19:02 +0000 Content-Type: multipart/mixed; boundary="----------=_1692620342-10931-1" This is a multi-part message in MIME format... ------------=_1692620342-10931-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Your bug report #59576: 29.0.50; named-let doesn't support dynamic binding which was filed against the emacs package, has been closed. The explanation is attached below, along with your original report. If you require more details, please reply to 59576@debbugs.gnu.org. --=20 59576: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D59576 GNU Bug Tracking System Contact help-debbugs@gnu.org with problems ------------=_1692620342-10931-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at 59576-done) by debbugs.gnu.org; 21 Aug 2023 12:18:10 +0000 Received: from localhost ([127.0.0.1]:55783 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qY3rG-0002pF-5U for submit@debbugs.gnu.org; Mon, 21 Aug 2023 08:18:10 -0400 Received: from mail33c50.megamailservers.eu ([91.136.10.43]:40851) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qY3rD-0002p4-Jb for 59576-done@debbugs.gnu.org; Mon, 21 Aug 2023 08:18:09 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1692620283; bh=MBqOsSyBCLutp4FwBsnsv0H2o6tm0/9YjNlqEPkIDsA=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=nFyWUDjHrdRnTpTWlaLWvxlguQtmTb5f5LbBkEzSqFIuN9WkjczAV/dr0Q3JAcEP+ x9QWNyQymA7gN9smUhUpHKVWVWbzrpClFhJz1kncG3saGX6A4UsCMlpPREEGGqnUoW GGlQEZXx7BNHyfgAXdd35g9bi2yxzNGo9imJTbbE= Feedback-ID: mattiase@acm.or Received: from smtpclient.apple (c188-150-165-235.bredband.tele2.se [188.150.165.235]) (authenticated bits=0) by mail33c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 37LCI0VF127207; Mon, 21 Aug 2023 12:18:02 +0000 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.120.0.1.15\)) Subject: Re: bug#59576: 29.0.50; named-let doesn't support dynamic binding From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= In-Reply-To: Date: Mon, 21 Aug 2023 14:17:59 +0200 Content-Transfer-Encoding: 7bit Message-Id: References: <8DE91C19-0401-4448-82E6-64AA96C677CE@acm.org> To: Stefan Monnier X-Mailer: Apple Mail (2.3654.120.0.1.15) X-VADE-SPAMSTATE: clean X-VADE-SPAMSCORE: -100 X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedviedrudduledghedtucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecujffquffvqffrkfetpdfqfgfvpdfgpfggqdevhedtnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpegtggfuhfgjffevgffkfhfvofesthejmhdthhdtvdenucfhrhhomhepofgrthhtihgrshcugfhnghguvghgnohrugcuoehmrghtthhirghsvgesrggtmhdrohhrgheqnecuggftrfgrthhtvghrnhepgfeufeelteduvedvkeevvdfhgeehjedvjeeigedvudefheegffejudefjefhjeffnecukfhppedukeekrdduhedtrdduieehrddvfeehnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepudekkedrudehtddrudeihedrvdefhedphhgvlhhopehsmhhtphgtlhhivghnthdrrghpphhlvgdpmhgrihhlfhhrohhmpehmrghtthhirghsvgesrggtmhdrohhrghdpnhgspghrtghpthhtohepfedprhgtphhtthhopehmohhnnhhivghrsehirhhordhumhhonhhtrhgvrghlrdgtrgdprhgtphhtthhopehtohhmlhgvvhihleefsehgmhgrihhlrdgtohhmpdhrtghpthhtohepheelheejiedqughonhgvseguvggssghughhsrdhgnhhurdhorhhg X-Origin-Country: SE X-Spam-Score: 0.3 (/) X-Debbugs-Envelope-To: 59576-done Cc: 59576-done@debbugs.gnu.org, Tom Levy X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) 26 nov. 2022 kl. 18.45 skrev Stefan Monnier : > Indeed, I'm surprised I didn't put something akin to (cl-assert > lexical-binding) in that macro. It was an oversight. Now done on master (c21103bb76). ------------=_1692620342-10931-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at submit) by debbugs.gnu.org; 25 Nov 2022 16:55:24 +0000 Received: from localhost ([127.0.0.1]:37045 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oybz1-0007MO-RE for submit@debbugs.gnu.org; Fri, 25 Nov 2022 11:55:24 -0500 Received: from lists.gnu.org ([209.51.188.17]:58144) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oybz0-0007MG-Cy for submit@debbugs.gnu.org; Fri, 25 Nov 2022 11:55:22 -0500 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 1oybyy-0001Xt-Ty for bug-gnu-emacs@gnu.org; Fri, 25 Nov 2022 11:55:21 -0500 Received: from [145.40.109.133] (helo=145.40.109.133) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oybyx-0008QG-07 for bug-gnu-emacs@gnu.org; Fri, 25 Nov 2022 11:55:20 -0500 Received: from root by 145.40.109.133 with local (Exim 4.94.2) (envelope-from ) id 1oybec-0001tP-MU for bug-gnu-emacs@gnu.org; Fri, 25 Nov 2022 16:34:18 +0000 From: Tom Levy To: bug-gnu-emacs@gnu.org Subject: 29.0.50; named-let doesn't support dynamic binding Message-Id: Date: Fri, 25 Nov 2022 16:34:18 +0000 X-Host-Lookup-Failed: Reverse DNS lookup failed for 145.40.109.133 (failed) Received-SPF: none client-ip=145.40.109.133; envelope-from=root@145.40.109.133; helo=145.40.109.133 X-Spam_score_int: 36 X-Spam_score: 3.6 X-Spam_bar: +++ X-Spam_report: (3.6 / 5.0 requ) BAYES_00=-1.9, DKIM_ADSP_CUSTOM_MED=0.001, FORGED_GMAIL_RCVD=1, FREEMAIL_FORGED_FROMDOMAIN=0.243, FREEMAIL_FROM=0.001, FSL_HELO_BARE_IP_1=2.347, HEADER_FROM_DIFFERENT_DOMAINS=0.25, NML_ADSP_CUSTOM_MED=0.9, NO_DNS_FOR_FROM=0.001, RDNS_NONE=0.793, SPF_NONE=0.001, SPOOFED_FREEMAIL=0.001, SPOOFED_FREEMAIL_NO_RDNS=0.001, SPOOF_GMAIL_MID=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Is `named-let' supposed to work when dynamic binding is used (as opposed to lexical binding)? Because if so, it is broken when the recursion is not in tail position. Example: ``` (eval '(named-let f ((x 10)) (if (= 0 x) 0 (1+ (f (1- x))))) ; note: recursion is *not* in tail position nil) ; change to t to enable lexical binding (makes the code work) ``` Output: ``` Debugger entered--Lisp error: (void-variable --cl-f--) (funcall --cl-f-- (1- x)) (1+ (funcall --cl-f-- (1- x))) (if (= 0 x) t (1+ (funcall --cl-f-- (1- x)))) (lambda (x) (if (= 0 x) t (1+ (funcall --cl-f-- (1- x)))))(10) funcall((lambda (x) (if (= 0 x) t (1+ (funcall --cl-f-- (1- x))))) 10) (named-let f ((x 10)) (if (= 0 x) t (1+ (f (1- x))))) eval((named-let f ((x 10)) (if (= 0 x) t (1+ (f (1- x))))) nil) (progn (eval '(named-let f ((x 10)) (if (= 0 x) t (1+ (f (1- x))))) nil)) eval((progn (eval '(named-let f ((x 10)) (if (= 0 x) t (1+ (f ...)))) nil)) t) elisp--eval-last-sexp(nil) eval-last-sexp(nil) funcall-interactively(eval-last-sexp nil) call-interactively(eval-last-sexp nil nil) command-execute(eval-last-sexp) ``` There is an easy fix. Currently `named-let' is defined as follows: ``` (defmacro named-let (name bindings &rest body) ;; ... (require 'cl-lib) (let ((fargs (mapcar (lambda (b) (if (consp b) (car b) b)) bindings)) (aargs (mapcar (lambda (b) (if (consp b) (cadr b))) bindings))) ;; According to the Scheme semantics of named let, `name' is not in scope ;; while evaluating the expressions in `bindings', and for this reason, the ;; "initial" function call below needs to be outside of the `cl-labels'. ;; When the "self-tco" eliminates all recursive calls, the `cl-labels' ;; expands to a lambda which the byte-compiler then combines with the ;; funcall to make a `let' so we end up with a plain `while' loop and no ;; remaining `lambda' at all. `(funcall (cl-labels ((,name ,fargs . ,body)) #',name) . ,aargs))) ``` I believe the issue is with the following construct: (funcall (cl-labels ((,name ...)) #',name) ...) The `funcall' to the lambda happens outside the scope of `cl-labels'. As stated in the documentation of `cl-labels', closure capture only works when lexical binding is in used. So any non-optimised recursive calls in the body will fail, because `name' is not captured. The easy fix is to move the `funcall' inside the scope of cl-labels. However the bindings must be evaluated outside the `cl-labels' (as explained in the existing comment). This can be achieved using a simple `let' outside the `cl-labels'. (This actually simplifies the code, because the bindings can be passed directly to `let' and the variable `aargs' can be eliminated.) Note that the generated bytecode with this fix is slightly different: it looks like, when all recursive calls are in tail position, this fix prevents the byte-compiler from inlining the outer function call. I am not sure if that's a significant problem. I included an example with disassembly below. (I am not including a patch because I haven't completed the copyright assignment process yet.) Cheers, Tom ------------ Disassembly example: ``` (let ((lexical-binding t)) (disassemble (byte-compile '(named-let f ((x 100000)) (if (= 0 x) 0 (f (1- x))))))) ; note: here recursion *is* in tail position ``` Output with current `named-let' implementation: ``` byte code: args: nil 0 constant 100000 1 constant nil 2:1 stack-ref 1 3 dup 4 constant 0 5 eqlsign 6 goto-if-nil 2 9 constant 0 10 stack-set 2 12 constant nil 13 goto 3 16:2 stack-ref 2 17 sub1 18 stack-set 3 20 constant :recurse 21:3 stack-set 1 23 goto-if-not-nil 1 26 return ``` Output with my proposed fix: ``` byte code: args: nil 0 constant doc: ... args: (arg1) 0 constant nil 1:1 stack-ref 1 2 dup 3 constant 0 4 eqlsign 5 goto-if-nil 2 8 constant 0 9 stack-set 2 11 constant nil 12 goto 3 15:2 stack-ref 2 16 sub1 17 stack-set 3 19 constant :recurse 20:3 stack-set 1 22 goto-if-not-nil 1 25 return 1 dup 2 constant 100000 3 call 1 4 return ``` And here is a minimal example showing that the byte-compile is unable to inline a `funcall' to a `let'-bound function: ``` (let ((lexical-binding t)) (disassemble (byte-compile '(let ((f #'(lambda (x) (message "%S" x)))) (funcall f 100000))))) ;; call to f is not inlined (let ((lexical-binding t)) (disassemble (byte-compile '(funcall #'(lambda (x) (message "%S" x)) 100000)))) ;; call to lambda is inlined ``` ------------ In GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu) of 2022-11-25 built on ... Repository revision: af545234314601ba3dcd8bf32e0d9b46e1917f79 Repository branch: master ------------=_1692620342-10931-1--