From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Monnier via "Emacs development discussions." Newsgroups: gmane.emacs.devel Subject: Re: combining cond and let, to replace pcase. Date: Sat, 25 Nov 2023 00:11:26 -0500 Message-ID: References: Reply-To: Stefan Monnier Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="22561"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) To: emacs-devel@gnu.org Cancel-Lock: sha1:a76UWGtdWT2QafGBEfZp5YVhFN0= Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Nov 25 06:12:34 2023 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 1r6ky1-0005l8-J5 for ged-emacs-devel@m.gmane-mx.org; Sat, 25 Nov 2023 06:12:33 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r6kx9-0008Tk-1X; Sat, 25 Nov 2023 00:11:39 -0500 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 1r6kx8-0008PU-0f for emacs-devel@gnu.org; Sat, 25 Nov 2023 00:11:38 -0500 Original-Received: from ciao.gmane.io ([116.202.254.214]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r6kx6-00040U-Bp for emacs-devel@gnu.org; Sat, 25 Nov 2023 00:11:37 -0500 Original-Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1r6kx2-0004XS-Po for emacs-devel@gnu.org; Sat, 25 Nov 2023 06:11:32 +0100 X-Injected-Via-Gmane: http://gmane.org/ Received-SPF: pass client-ip=116.202.254.214; envelope-from=ged-emacs-devel@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.25, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no 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:313196 Archived-At: > (cond* [...] > ;; Extracts substructure and binds variables around the rest > ;; of the cond*. > (:match (`(expt ,foo ,bar) x) > do-this-if-it-matched-then-exit...) > ;; Bindings continue in effect. Which bindings? Presumably when we continue the match failed, so `foo` and `bar` don't have any meaningful value to take, AFAICT. IOW we're continuing with the bindings that existed *before* the `:match`, but not with the bindings introduced by the `:match`, right? > ;; Like above but always falls thru to next clause. > (:match (`(expt ,foo ,bar) x)) > ;; Bindings continue in effect. What happens if `(car x)` is not equal to `expt` or if `x` is a string? > (match PATTERN VALUE) > This is a macro. > PATTERN is a backquote form which specifies which parts of > VALUE should be fixed. For instance > (match `(+ (expt nil nil)) (get-complex-list)) > would decompose the result of (get-complex-list) and check > for `+' and `expt' in it. > > PATTERN will not be evaluated, just used as guidance when the > `match' form is macroexpanded. > > If PATTERN includes substitutions, it will virtually perform > those substitutions and compare parts of VALUE against them. > (match `(foo ,foo) x) compares (car x) with `foo' and > compares (cadr x) with the value of foo. > > `match' can also handle vectors and maybe some other kinds of > structures. Don't we have that under the name `equal`? I mean I understand you intend the above `match` to work without memory allocation, but it seems that it's just an optimization. Or am I missing something? > (match-set PATTERN VALUE) > This is a macro. > PATTERN is a backquote form which specifies which parts of > VALUE to match and parts to extract and store. For instance > (match-set `(+ ,y ,z) (get-complex-list)) > would decompose the result of (get-complex-list), verify the car, > and set y and z. > > PATTERN will not be evaluated, just used as guidance when the > `match-set' form is macroexpanded, producing code like this: (defalias 'match-set #'pcase-setq) 🙂 > (match-bind PATTERN VALUE BODY...) > Much like `match-set', except that instead of setting the > variables found in PATTERN, it let-binds them and runs BODY > with those bindings. This one is not a mere `defalias`: (defmacro match-bind (pattern value &rest body) `(pcase-let ((,pattern ,value)) ,@body)) There's a tradeoff here, indeed: sometimes I find the added ((...)) of `pcase-let` rather annoying, but other times the fact that it's a superset of `let` means I get to mix it with normal bindings without increasing the nesting depth, which improves readability. Stefn