From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Richard Stallman Newsgroups: gmane.emacs.devel Subject: Re: combining cond and let, to replace pcase. Date: Wed, 22 Nov 2023 21:58:54 -0500 Message-ID: References: Reply-To: rms@gnu.org Content-Type: text/plain; charset=Utf-8 Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="19663"; 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 23 03:59:05 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 1r5zvl-0004tp-Ej for ged-emacs-devel@m.gmane-mx.org; Thu, 23 Nov 2023 03:59:05 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r5zvd-0001GX-5A; Wed, 22 Nov 2023 21:58:57 -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 1r5zvb-0001GB-Cy for emacs-devel@gnu.org; Wed, 22 Nov 2023 21:58:55 -0500 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r5zvb-0000MX-5E for emacs-devel@gnu.org; Wed, 22 Nov 2023 21:58:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=Date:References:Subject:In-Reply-To:to:From: mime-version; bh=4a+FjyBhvNWUeLADmdODdTJyd9+8ujgFXCxxw7CnJoo=; b=mGOPvWA++mCI 5c3o+YEi/RhAS7q1Sq+Nh7O9YMBNZbduYN4P/yTSIRle+U7Sp+Ji5c/wJLo6rENtNK7Kb/k5BatNs nnBytdHLvhTnz+YwCrWIXTZK1BMWlYS9GtC1w0n6+0470EYSkIYeOvXeK5kONTn8BlyyIFdlVB4y7 +NFVCnnkuF2eYoa0imEv5gd1Ro+olf9NoB6HGYBT0ews8bt+ofXxibPGZz73sihW/AdjTsBJhzz9g wCPMUhrl7B05uuT25+NUEuDFfVlMyB3JCMochlSkt3iDKOIwGLHJFmjjWPVOhj5mJHLruhktiaDOF UBSeapTnyyr/dqywnx445A==; Original-Received: from rms by fencepost.gnu.org with local (Exim 4.90_1) (envelope-from ) id 1r5zva-0006B6-JQ; Wed, 22 Nov 2023 21:58:54 -0500 In-Reply-To: (message from Richard Stallman on Fri, 17 Nov 2023 22:03:56 -0500) 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:313137 Archived-At: [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] I've done more work on designing `cond*'; here is what I have now. Please send me constructive suggestions, including for features you suggest adding. (cond* ;; Same as a clause in `cond', (CONDITION do-this-if-CONDITION-then-exit...) ;; Variables to bind, as in let (:bind (x foobar) y z (foo 5) a) ;; Bindings continue in effect. ;; t as condition means run this clause unconditionally ;; then always continue with next clause. (t do-this-unconditionally-and-dont-stop...) ;; 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. ;; Like above but always falls thru to next clause. (:match (`(expt ,foo ,bar) x)) ;; Bindings continue in effect. ;; t in the last clause means the same as in previous clauses, ;; but you can think of it as being the same as in `cond'. (t do-this-as-last-resort...) ) Here are three macros that would be useful as conditions in `cond*' but can also be used elsewhere. (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. (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: (if (eq (car value) '+) (progn (setq y (car (cadr value)) z (cadr (cadr value))) t)) `match' can also handle vectors and maybe some other kinds of structures. (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. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org)