GNU bug report logs - #59576
29.0.50; named-let doesn't support dynamic binding

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: emacs; Severity: wishlist; Reported by: Tom Levy <tomlevy93@HIDDEN>; Keywords: wontfix; dated Fri, 25 Nov 2022 16:56:02 UTC; Maintainer for emacs is bug-gnu-emacs@HIDDEN.
Added tag(s) wontfix. Request was from Stefan Kangas <stefankangas@HIDDEN> to control <at> debbugs.gnu.org. Full text available.
Severity set to 'wishlist' from 'normal' Request was from Stefan Kangas <stefankangas@HIDDEN> to control <at> debbugs.gnu.org. Full text available.

Message received at 59576 <at> debbugs.gnu.org:


Received: (at 59576) by debbugs.gnu.org; 26 Nov 2022 17:45:53 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 26 12:45:53 2022
Received: from localhost ([127.0.0.1]:41379 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1oyzFQ-00035y-Pu
	for submit <at> 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 <monnier@HIDDEN>) id 1oyzFO-00035r-Qv
 for 59576 <at> 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 <monnier@HIDDEN>
To: Mattias =?windows-1252?Q?Engdeg=E5rd?= <mattiase@HIDDEN>
Subject: Re: bug#59576: 29.0.50; named-let doesn't support dynamic binding
In-Reply-To: <8DE91C19-0401-4448-82E6-64AA96C677CE@HIDDEN> ("Mattias
 =?windows-1252?Q?Engdeg=E5rd=22's?= message of "Sat, 26 Nov 2022 10:48:54
 +0100")
Message-ID: <jwvmt8dk3ua.fsf-monnier+emacs@HIDDEN>
References: <8DE91C19-0401-4448-82E6-64AA96C677CE@HIDDEN>
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: =?UTF-8?Q?0=0A=09?=ALL_TRUSTED -1 Passed
 through trusted hosts only via =?UTF-8?Q?SMTP=0A=09?=AWL -0.168 Adjusted
 score from AWL reputation of From: =?UTF-8?Q?address=0A=09?=BAYES_00 -1.9
 Bayes spam probability is 0 to 1%
 DKIM_SIGNED               0.1 Message has a DKIM or DK signature,
 not necessarily =?UTF-8?Q?valid=0A=09?=DKIM_VALID -0.1 Message has at least
 one valid DKIM or DK =?UTF-8?Q?signature=0A=09?=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-Debbugs-Envelope-To: 59576
Cc: Tom Levy <tomlevy93@HIDDEN>, 59576 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
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





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#59576; Package emacs. Full text available.

Message received at 59576 <at> debbugs.gnu.org:


Received: (at 59576) by debbugs.gnu.org; 26 Nov 2022 10:36:55 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 26 05:36:54 2022
Received: from localhost ([127.0.0.1]:37917 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1oysYI-0004eK-Kr
	for submit <at> 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 <tomlevy93@HIDDEN>) id 1oysYG-0004e6-H8
 for 59576 <at> 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 <at> 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@HIDDEN>
In-Reply-To: <8DE91C19-0401-4448-82E6-64AA96C677CE@HIDDEN>
From: Tom Levy <tomlevy93@HIDDEN>
Date: Sat, 26 Nov 2022 23:36:10 +1300
Message-ID: <CAMtU5-hTjPus1JdcNvkBv-NR3igxc=_g-PSrkxciEOqtyKzjKQ@HIDDEN>
Subject: Re: bug#59576: 29.0.50; named-let doesn't support dynamic binding
To: =?UTF-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: 0.2 (/)
X-Debbugs-Envelope-To: 59576
Cc: Stefan Monnier <monnier@HIDDEN>, 59576 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
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 <mattiase@HIDDEN> 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.)
>




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#59576; Package emacs. Full text available.

Message received at 59576 <at> debbugs.gnu.org:


Received: (at 59576) by debbugs.gnu.org; 26 Nov 2022 09:49:13 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 26 04:49:13 2022
Received: from localhost ([127.0.0.1]:37853 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1oyro9-0003QA-GZ
	for submit <at> 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 <mattiase@HIDDEN>) id 1oyro6-0003Pv-Pg
 for 59576 <at> debbugs.gnu.org; Sat, 26 Nov 2022 04:49:12 -0500
X-Authenticated-User: mattiase@HIDDEN
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@HIDDEN
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: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= <mattiase@HIDDEN>
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\))
Subject: bug#59576: 29.0.50; named-let doesn't support dynamic binding
Message-Id: <8DE91C19-0401-4448-82E6-64AA96C677CE@HIDDEN>
Date: Sat, 26 Nov 2022 10:48:54 +0100
To: Tom Levy <tomlevy93@HIDDEN>
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-Debbugs-Envelope-To: 59576
Cc: Stefan Monnier <monnier@HIDDEN>, 59576 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
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.)





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#59576; Package emacs. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 25 Nov 2022 16:55:24 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Nov 25 11:55:24 2022
Received: from localhost ([127.0.0.1]:37045 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1oybz1-0007MO-RE
	for submit <at> 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 <root@HIDDEN>) id 1oybz0-0007MG-Cy
 for submit <at> 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 <root@HIDDEN>)
 id 1oybyy-0001Xt-Ty
 for bug-gnu-emacs@HIDDEN; 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 <root@HIDDEN>)
 id 1oybyx-0008QG-07
 for bug-gnu-emacs@HIDDEN; Fri, 25 Nov 2022 11:55:20 -0500
Received: from root by 145.40.109.133 with local (Exim 4.94.2)
 (envelope-from <root@HIDDEN>) id 1oybec-0001tP-MU
 for bug-gnu-emacs@HIDDEN; Fri, 25 Nov 2022 16:34:18 +0000
From: Tom Levy <tomlevy93@HIDDEN>
To: bug-gnu-emacs@HIDDEN
Subject: 29.0.50; named-let doesn't support dynamic binding
Message-Id: <E1oybec-0001tP-MU@HIDDEN>
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@HIDDEN;
 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 <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
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  <compiled-function>
      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




Acknowledgement sent to Tom Levy <tomlevy93@HIDDEN>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs@HIDDEN. Full text available.
Report forwarded to bug-gnu-emacs@HIDDEN:
bug#59576; Package emacs. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Sat, 3 Dec 2022 01:15:02 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.