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: Yuri Khan
Subject: Re: combining cond and let, to replace pcase.
Date: Tue, 28 Nov 2023 01:49:10 +0700

On Tue, 28 Nov 2023 at 01:14, Manuel Giraud via Emacs development
discussions. <emacs-devel@gnu.org> wrote:
>
> Richard Stallman <rms@gnu.org> writes:
>
> [...]
>
> >   > >        ;; 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?
> >
> > This form of clause should bind the variables unconditionally.  If
> > matching provides a value to give a certain variable, the variable
> > should get that value.  Otherwise it should be bound to nil.
>
> So these form of :match clause would bind variables even though it did
> not match?  That seems counter-intuitive to me.

Not only that, it’s just plain wrong.

    (pcase 42
      (`(,x . ,y) (format "%s:%s" x y))
      (_ "not a cons cell"))
    → not a cons cell

If I understand Richard correctly, the corresponding :match will
unconditionally attempt to bind x to (car 42) and y to (cdr 42), which
results in a run-time error.

The correct pattern matching behavior is to first check that the
expression being matched is indeed a cons, and only if so, destructure
it into its car and cdr.

Similarly, attempting to match a two-element list (expt 2) with a
three-element pattern (expt ,x ,y) is nonsensical and it’s not helpful
to bind y to (caddr '(expt 2)) == nil. Same if the list and pattern
have the same length but literal elements do not match, e.g. '(+ 42
73) against '(expt ,base ,exponent).



reply via email to

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