[Top][All Lists]

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

pcase vs. case (where it could also be used) [Was: Re: Replace trivial p

From: Garreau\, Alexandre
Subject: pcase vs. case (where it could also be used) [Was: Re: Replace trivial pcase occurrences in the Emacs sources]
Date: Tue, 23 Oct 2018 21:52:01 +0200
User-agent: Gnus (5.13), GNU Emacs 25.1.1 (i686-pc-linux-gnu, GTK+ Version 3.22.11) of 2017-09-15, modified by Debian

On 2018-10-23 at 14:12, Stefan Monnier wrote:
> In the specific case of using `pcase` where `cl-case` could also be
> used, the downsides I know of `pcase` are the following:

> - if you forget to quote your constant symbols the code behaves
>   differently (and arguably surprisingly for some user) rather than
>   giving you an error, tho in many cases the macro will detect a problem
>   and give you a warning about a subsequent redundant branch (but the
>   unsuspecting user will likely find it puzzling and it will take
>   a while for him to figure out what's going on).

Aren’t non-quoted for bind? what should give an error or a warning? I
didn’t understood?

Also, in either pcase or case: can’t they eval a symbol as a variable
value to be used in tests?

> [but] because it can also do a lot more, its doc is much more complex.

> The advantages are:

> - it can accommodate many more cases, so it offers a smoother evolution.
>   IOW, you will rarely find yourself having to stop using `pcase` and
>   to rewrite the code to use `cond` instead just because you need to
>   add a case that's a bit different from the others.

To push the reasoning on an extreme: would that be a reason for
abandoning cond, lambda, etc. in favor of pcase?  ML do that, and I find
it sad and less minimal and lightweight.

> - once you learn it, you can use it elsewhere, e.g. pcase-let,
>   pcase-dolist, ...

Could have been the same for cl-destructuring-bind.

> - Elisp+pcase is simpler than Elisp+clcase+pcase, so if we aim for
>   overall simplicity we'd be better off without cl-case (to the extend
>   that `cl-case` is too limited and hence we'll still want to use
>   `pcase`).

> the advantages I see for `cl-case`:

You forgot simplicity and concision of implementation: easier to
understand and reimplement, thus more hackable upon and widespread.  For
instance, I personally have my own case* implementation for using other
test-fn than eql (such as equal, the only possible one for pcase, and I
don’t even hope making my own version for eq/eql/etc.).

Many people will want case anyway, probably much code uses it (including
but not limited to fragments of common lisp afaik), so it’ll stay
anyway, because it is a trivial and obvious factorization of cond,
already existing in most languages, and simpler to make.  While pcase is
much more questionable, trivial, straightforward and widespread.
elisp+clcase is simpler than elisp+pcase, overall.  So for any codebase,
one only needing case (more likely) will be simpler and have less
dependency burden that one needing pcase.

Also, from a more reductionist point of view: pcase can be implemented
more simply and readably using case, typecase, etc.  so that’s yet
another argument for case to stay used and widespread.

> - easier for people who already know Common-Lisp (or those who learned
>   `case` from the cl.el package).

Also it is basically the equivalent of “switch/case/etc.” many will
search for, coming from another language such as C: and not everybody is
fond of destructuring and pattern matching

> Here are the problems I see with cl-case (regardless of pcase):

> - only works with numbers and symbols: can't use it to match against
> strings.

Can be fixed, and without breaking backward-compatibility.

> - in (case X (a fooa)), the syntax looks a bit like a call to the
> function `a`: emacs-lisp-mode gets confused in terms of highlighting
> and completion, last I checked.

case is a macro: why making assumption on calls in macros arguments?
from time case known as a macro (I’ve a hard time imagining what a
“case” *function* would be anyway)…  Also, with an unquoted symbol (so
to bind the default case), you have this very same problem with pcase:
(pcase X (a (fooa))) (and emacs syntax highlighting is confused here
too: (pcase X (cond (fooa))), (pcase X (function (fooa))).  So
emacs-lisp-mode would better be fixed at some point rather than macros
arbitrarily disapproved.  Then:
> - [pcase] fixes all four problems I described about `cl-case`.
hence not even.

> - tricky corner cases when trying to match the `t` or `nil` values (or
>   `otherwise` as well, tho this one is much more rarely needed).

I find these interface details sadening, it would have been more useful
the other way.  Btw as said before, matching the default case can be
considered confusing as well with pcase.

> - some users naturally write (case X ('a fooa) ...) without realizing
>   that it also matches thew `quote` value.

I find sad cl case doesn’t eval its arguments :/ The two last issue
would be lessened it it was this way btw.  But doing otherwise would be
incompatible with cl, with which I find neat emacs lisp is partially
compatible with, and it would break backward-compatibility, and much
code (as much as it would to remove it at all).

reply via email to

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