emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: cond*


From: Ihor Radchenko
Subject: Re: cond*
Date: Mon, 01 Jan 2024 14:49:37 +0000

Richard Stallman <rms@gnu.org> writes:

> Each clause in cond* that has just one element -- no "clause body" --
> is a "non-exit" clause.  After that clause completes, control always
> proceeds to the following clause.
> ...
> To test CONDITION and return its value if non-nil, use this:
>
>        (CONDITION CONDITION)

Note that it is different from `cond', which is somewhat confusing -
(CONDITION) in `cond' exits, returning CONDITION value.

> A backquoted cons cell
>
> ...
> (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).

This is more confusing than `pcase'. In `pcase', what you call
"cdr-safe" is realized simply by `(a b . _) and what you cal ""cdr" is
`(a b). I find `pcase' version both more intuitive and more compact.

> Constrained variable: (PRED VARIABLE)  or, more generally,
>                       (PRED VARIABLE OTHER-ARGS...)
>
>   This matches any value VALUE that satisfies the specified
>   constraint.  PRED is a function to test the constraint.  It receives
>   VALUE as its first argument.  If PRED returns true, that means VALUE
>   satisfies the constraint, so this pattern binds (or sets) VARIABLE
>   to that value.  For instance,
>
>      (symbolp sym)   ; Match any symbol, bind `sym' to it.

This is an equivalent of pcase's pred pattern, except that pcase also
allow VARIABLE to be non-first argument of PRED.
What about allowing a construct like ,((plist-get plist) property) that
will test for PROPERTY being in PLIST?

Or, better, allow VARIABLE to be in an arbitrary argument of PRED:

,(PRED ARG1 ARG2 !VARIABLE ARG3 ...)
Example: ,(plist-get plist !variable #'equal)

> xxxxxxxxxxxxxx not decided yet
>     This would give some added power, but does that power really enable
>     the user to do more with cond*?  I am not sure.
>
>   PATTERN can also be a list, which is a pattern to destructure,
>   For instance,
>
>      (plistp `(,a ,b . ,rest))
>
>   checks that VA<UE is a valid plist, then binds a and b to the first
>   and second element and binds rest to its cddr.
> xxxxxxxxxxxxxx not decided yet

I feel that layering conditions will lead to unnecessary complexity.
What about allowing (and ...) pattern, similar to (or ...):

(match* (and (plistp _) `(,a ,b . ,rest)) plist)

P.S. What is missing in the above compared to pcase is matching regular
expressions:

‘(rx RX-EXPR...)’
     Matches strings against the regexp RX-EXPR..., using the ‘rx’
     regexp notation (*note Rx Notation::), as if by ‘string-match’.

     In addition to the usual ‘rx’ syntax, RX-EXPR... can contain the
     following constructs:

     ‘(let REF RX-EXPR...)’
          Bind the symbol REF to a submatch that matches RX-EXPR....
          REF is bound in BODY-FORMS to the string of the submatch or
          ‘nil’, but can also be used in ‘backref’.

     ‘(backref REF)’
          Like the standard ‘backref’ construct, but REF can here also
          be a name introduced by a previous ‘(let REF ...)’ construct.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]