From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: pcase generates an unprintable expansion for a form in test erc--restore-initialize-priors Date: Mon, 27 May 2024 13:39:47 -0400 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="20197"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: emacs-devel@gnu.org To: Alan Mackenzie Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Mon May 27 19:40:33 2024 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 1sBeKn-00052H-Oz for ged-emacs-devel@m.gmane-mx.org; Mon, 27 May 2024 19:40:33 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sBeKG-00071c-2U; Mon, 27 May 2024 13:40:00 -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 1sBeKB-0006xo-3Q for emacs-devel@gnu.org; Mon, 27 May 2024 13:39:56 -0400 Original-Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sBeK8-0008Ih-KF for emacs-devel@gnu.org; Mon, 27 May 2024 13:39:54 -0400 Original-Received: from pmg3.iro.umontreal.ca (localhost [127.0.0.1]) by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id 0C9AB442735; Mon, 27 May 2024 13:39:50 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1716831588; bh=zonNxchgCivFd8G6UTMU5hRjj/0zV/zMjfSNmJd6hJU=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=bu0XJtka/S4BVy3x2nZ2zAC0uyUIfyyAId3S239AJJmmbCQ58OQd2Rj+Y3nZwS24z b1hjK7Ir1UnKPBY0vEPCCCm6mpeJCDfefQ90iC+fibv4X+yB2IplbObH7I7En0jfA8 o3P2njMxoeyMVNZ6vztsPkLHM8HqCO1xM672S7CLXmKYTFpTyXq+crl2C0rwO6QjPM 8LC96vQ7osOqDU4CYFnOzFCC0PzSdOxDmdRyTbmalrxb9RYdBBXxs2evEJcViVOTAV bYxBWpJhkVNwNx49n+fbyYPc+O0g9MVrU0zKPVnOd72SY3YvfENAU09mBkgX8Qa/a8 /Hh8GRO4ffF7Q== Original-Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id 6C42C44272C; Mon, 27 May 2024 13:39:48 -0400 (EDT) Original-Received: from alfajor (unknown [23.233.149.155]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 5103F1202E4; Mon, 27 May 2024 13:39:48 -0400 (EDT) In-Reply-To: (Alan Mackenzie's message of "Sun, 26 May 2024 15:30:19 +0000") Received-SPF: pass client-ip=132.204.25.50; envelope-from=monnier@iro.umontreal.ca; helo=mailscanner.iro.umontreal.ca X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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:319620 Archived-At: > (should (pcase (macroexpand-1 '(erc--restore-initialize-priors erc-my-mode > foo (ignore 1 2 3) > bar #'spam > baz nil)) > (`(let* ((,p (or erc--server-reconnecting erc--target-priors)) > (,q (and ,p (alist-get 'erc-my-mode ,p)))) > (unless (local-variable-if-set-p 'erc-my-mode) > (error "Not a local minor mode var: %s" 'erc-my-mode)) > (setq foo (if ,q (alist-get 'foo ,p) (ignore 1 2 3)) > bar (if ,q (alist-get 'bar ,p) #'spam) > baz (if ,q (alist-get 'baz ,p) nil))) > t)))) Hmm... Looking at it from a `pcase.el` perspective, the above pattern represents a really large number of conditions :-) > .. Note that the pcase form is expanding a backquoted form lacking in > pcase features such as nested backquotes, pcase variable names, and the > like. [ I didn't understand what you meant here, sorry. ] > The pcase expansion thus consists of a deeply nested alternation of forms > like > (if (consp x1961) ...) > and > (let* ((x1962 (car-safe x1961))) ...) > .. Oh, yes! > The level of nesting is greater than, or close enough to 200 that > printing it can lead to the detection of an apparent circular structure > in print_object in src/print.c. There PRINT_CIRCLE is #defined as 200. I'm surprised it doesn't also cause errors during compilation (because of too deeply nested recursive calls). > The form being compared using pcase, although not tiny, is not all that > big, and it would be easy to increase its size to cause it to violate any > reasonable value of PRINT_CIRCLE. Agreed. > Would it be possible and a good idea to amend pcase such that it > generates less deeply nested expansions for forms such as we have here? A good idea? Definitely. Possible? No doubt. Not sure how easy it would be, OTOH. FWIW, this is a case where the compilation strategy Richard uses in `cond*` probably works better. I think the main thing to do here would be to see how to recognize subpatterns that don't have any `,` in them so we can match them with a simple `equal` test. E.g. the whole (unless (local-variable-if-set-p 'erc-my-mode) (error "Not a local minor mode var: %s" 'erc-my-mode)) subpattern can be matched much more efficiently with a single `equal`, I suspect it can be done with no change to the core pcase code by rewriting (pcase-defmacro \` (qpat) so it does the recursion on its own (e.g. instead of expanding `(A . B) to a pattern which contains `A and `B). Then at any level if it notices that no `,` was found during the recursion it can just use `equal`. Another approach would be to change the "back end" of pcase so that when we built the nested `let*/if` monster we recognize specific patterns that can be rewritten more compactly. > Or does anybody have any ideas how better to resolve the problem? FWIW, I'm wondering what's the value of this specific test. Do we really care about the specific shape of the returned code? It seems terribly brittle: every minute change to the macro will require matching changes to the test, and I have no idea what is the intention of this test so if it every fails I wouldn't know whether the error is in the test or in the code. Stefan