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: cond* Date: Sun, 17 Dec 2023 23:09:36 -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="10109"; 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 Mon Dec 18 05:10:25 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 1rF4xU-0002Ox-TL for ged-emacs-devel@m.gmane-mx.org; Mon, 18 Dec 2023 05:10:25 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rF4wm-0007T0-Od; Sun, 17 Dec 2023 23:09:40 -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 1rF4wk-0007Sr-Gs for emacs-devel@gnu.org; Sun, 17 Dec 2023 23:09:38 -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 1rF4wj-0002hy-GP for emacs-devel@gnu.org; Sun, 17 Dec 2023 23:09:38 -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=bAvddUD9+cS+j/o/lXi+v8oYV+fPNc0zk9y6WIkZAjw=; b=OgQavuFcJfNk 5a/Aa/B+Rka3ovPs0MpuFx0wUzTwj7CxUqYwgxjqG/AToF6hj8rQlkX3J492mvCVEsdrxdzrsIwnd 4U/9MYNNaMHmwH09RiF7Hw12xqd+zlI7DSgC5McmbITUxqwFcvp7kkHioiI7RCa6aNOjOEHtjdj/J xum5L0KbiemThbGt5UNmdvY2aEJlpaPOFYy4u8eONe0pQJc9+1awNfnwL7Y/Tb5dH4BaghRkIjZXA iPF5bRTk0PtAbVGF91Mdxz8OMAQenEuZS0P5RV1Rddt5c+qysGdWPta/xLCaA/v1r/+rqPXRbLftg Qy1LyEQpFmLCnj2A1xiEpQ==; Original-Received: from rms by fencepost.gnu.org with local (Exim 4.90_1) (envelope-from ) id 1rF4wi-0006Q3-Ne; Sun, 17 Dec 2023 23:09:36 -0500 In-Reply-To: (message from Richard Stallman on Fri, 15 Dec 2023 23:23:55 -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:313968 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 made cond*'s syntax more Lispy by changing (:match (PATTERN DATA) to ((match* PATTERN DATA) and likewise (:bind VARLIST to ((bind* VARLIST...) This means that cond* no longer uses keywords itself. This simplifies the criterion for a fall-through clause: it has one exactly element. The proposed macros `match' and `match-bind' are not necessary because you can use (cond* ((match* PATTERN DATA) t)) and (cond* ((match* PATTERN DATA) BODY...)) which are hardly more complex to use. So I have eliminated those macros from the proposal. I've tentatively added a new kind of clause, ((match-set* PATTERN DATA) which sets pattern variables without binding them. That can be used instead of the previously proposed macro, `match-set'. But I am not sure whether this feature is really worth its added complexity. Maybe in the end it should be omitted. Each clause exits if it contains more than one element, and falls through otherwise. (cond* ;; Same as a clause in `cond', (CONDITION DO-THIS-IF-TRUE-THEN-EXIT...) ;; Execute FORM and ignore its value. (FORM) ;; Variables to bind, as in let*, around the rest ;; of the cond*. ((bind* (x foobar) y z (foo 5) a)) ;; Bindings continue in effect for the whole cond* construct. ;; Bind variables for the clause, as in let*. ((bind* (foo 5) (condition (hack-it foo))) ;; condition is that the last variable bound be non-nil. BODY...) ;; Bindings no longer in effect. ;; Extracts substructure and binds variables for the clause. ((match* `(expt ,foo ,bar) x) DO-THIS-IF-IT-MATCHED-THEN-EXIT...) ;; Bindings no longer in effect. ;; Extracts substructure and binds variables ;; for the rest of the cond*. ;; Like above but always falls thru to next clause. ;; All the variables mentioned in the pattern ;; are bound whether match succeeds or not. ;; If a value can be determined from an incomplete match, ;; the variable gets that value. ((match* `(expt ,foo ,bar) x)) ;; Bindings continue in effect. ;; Another example of fall-through match* clause. ;; All the variables mentioned in the pattern ;; are bound in all cases. ((match* (or `() `(,macroexp-const-p const)) body) ;; The `match-set*' is a tentative proposal. It may not be worth including. ;; Extracts substructure and sets variables if match succeeds ((match-set* `(expt ,foo ,bar) x) DO-THIS-IF-IT-MATCHED-THEN-EXIT...) ;; Extracts substructure and sets variables without binding them. ;; Always falls thru to next clause. ((match-set* `(expt ,foo ,bar) x)) ) To execute several expressions and not exit, use this: ((progn DO-THIS-UNCONDITIONALLY-AND-DONT-STOP...) To test a condition and return its value if non-nil, use this: ((bind* (value CONDITION)) value) That has a small fixed amount of extra complexity compared with a one-element cond clause, but given that those are not very common, this is a small price to pay. **Possible types of patterns for match*. CONSTANT: nil, t, a keyword, a quoted constant other than a cons cell, fixed parts of a backquote. This matches any value equal to CONSTANT. _ _ means to match any value and not store it anywhere. VARIABLE: a symbol A symbol means to match any value and set VARIABLE to it. A quoted cons cell The car and the cdr are subpattenrs. The cons cell pattern matches any cons cell whose car and cdr match those two subpatterns. How nil as a cdr matches is controlled by the match-nil flag. When the nil-match-all flag is false, nil as a cdr matches only nil itself. When the nil-match-all flag is true, nil as a cdr matches any object and ignores that object. The nil-match-all flag is false by default. The `cdr' pattern maks it false within its its subpattern, and the `cdr-safe' pattern makes it true forwithin its its subpattern. (cdr-safe QUOTED-CONS-CELL) This pattern is equivalent to QUOTED-CONS-CELL by itself except that it makes the nil-match-all flag true within it. (cdr-safe `(a b)) matches (a b), (a b c), (a b . d), etc. (cdr QUOTED-CONS-CELL) This pattern is equivalent to QUOTED-CONS-CELL by itself except that it makes the nil-match-all flag false within it. (cdr `(a b)) matches only (a b). Constrained variable: (TESTFN VARIABLE OTHER-ARGS...) This matches any value VALUE provided (TESTFN VALUE OTHER-ARGS...) evaluates to true. If so, it sets VARIABLE to VALUE. (symbolp sym) Match any symbol, store it in `sym'. (> num-foos 1) Match any thing greater than 1, store it in `num-foos'. When matching to bind variables, this pattern unconditionally binds VARIABLE whether it matches or not. `quote', `constrain' and `or' cannot be used as TESTFN. Constrained variable constructs can be nested. For example, (< (numberp num-foos) 1) Match any number > 1, store it in mum-foos. General constrained variable: (constrain VAR EXPRESSION) This general constrained variable pattern binds VAR to the value being matched against, only for evaluating EXPRESSION. If the result is non-nil, the match succeeds and sets VAR to the value. For instance, (constrain x (and (> x 0) (< x 100))) Alternatives: (or SUBPATTERNS...) This tries to match each of the SUBPATTERNS in order until one matches. If the pattern is being used to bind variables, it binds all the variables specified in any of SUBPATTERNS -- 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)