emacs-devel
[Top][All Lists]
Advanced

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

Re: pcase bindings in patterns with complicated logic


From: Ihor Radchenko
Subject: Re: pcase bindings in patterns with complicated logic
Date: Sat, 13 Jan 2024 19:58:07 +0000

Richard Stallman <rms@gnu.org> writes:

> (pcase '(foo 5)
>   ((or `(,(and (pred symbolp) a1) ,(and (pred symbolp) b1))
>        `(,(and (pred symbolp) a2) ,(and (pred numberp) b2)))
>    `(,a1 ,b1 ,a2 ,b2)))
>
> => (nil nil foo 5)
>
> That surrised me, since outside the pcase, all four variables
> are unbound and referring to them gets errors.
>
> So it seems that all the pattern variables in the curren clause are
> bound somehow if that clause succeeds, but only some of them get
> significant values.
>
> Is that an accurate general statement of how pcase handles binding
> pattern variables?

This looks like a bug.
The manual has a dedicated paragraph explaining the above scenario.
However, on the latest Emacs master, "void variable" errors are not
thrown, in contradiction with what the manual states.

  3. On match, the clause's body forms can reference the set of symbols
     the pattern let-binds.  When SEQPAT is ‘and’, this set is the union
     of all the symbols each of its sub-patterns let-binds.  This makes
     sense because, for ‘and’ to match, all the sub-patterns must match.

     When SEQPAT is ‘or’, things are different: ‘or’ matches at the
     first sub-pattern that matches; the rest of the sub-patterns are
     ignored.  It makes no sense for each sub-pattern to let-bind a
     different set of symbols because the body forms have no way to
     distinguish which sub-pattern matched and choose among the
     different sets.  For example, the following is invalid:

          (require 'cl-lib)
          (pcase (read-number "Enter an integer: ")
            ((or (and (pred cl-evenp)
                      e-num)      ; bind ‘e-num’ to EXPVAL
                 o-num)           ; bind ‘o-num’ to EXPVAL
             (list e-num o-num)))

          Enter an integer: 42
          error→ Symbol’s value as variable is void: o-num
          Enter an integer: 149
          error→ Symbol’s value as variable is void: e-num



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