emacs-devel
[Top][All Lists]
Advanced

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

Re: combining cond and let, to replace pcase.


From: Stefan Monnier
Subject: Re: combining cond and let, to replace pcase.
Date: Sat, 25 Nov 2023 00:11:26 -0500
User-agent: Gnus/5.13 (Gnus v5.13)

> (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




reply via email to

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