emacs-devel
[Top][All Lists]
Advanced

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

Re: Replace trivial pcase occurrences in the Emacs sources


From: Stefan Monnier
Subject: Re: Replace trivial pcase occurrences in the Emacs sources
Date: Wed, 24 Oct 2018 16:52:23 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

>     (pcase this-param
>       ('edit (todo-edit-item--text))
>       ('header (todo-edit-item--text 'include-header))
>       ('multiline (todo-edit-item--text 'multiline))
>       ('add/edit (todo-edit-item--text 'comment-edit))
>       ('delete (todo-edit-item--text 'comment-delete))
>       ('diary (todo-edit-item--diary-inclusion))
>       ('nonmarking (todo-edit-item--diary-inclusion 'nonmarking))
>       [...]

Is the below any better?

    (cond
      ((eq this-param 'edit) (todo-edit-item--text))
      ((eq this-param 'header) (todo-edit-item--text 'include-header))
      ((eq this-param 'multiline) (todo-edit-item--text 'multiline))
      ((eq this-paran 'add/edit) (todo-edit-item--text 'comment-edit))
      ((eq this-parom 'delete) (todo-edit-item--text 'comment-delete))
      ((eq this-param 'diary) (todo-edit-item--diary-inclusion))
      ((eq this-param 'nonmarking) (todo-edit-item--diary-inclusion 
'nonmarking))
      [...]

To me, it's more verbose and more complex because you need to double
check that the same var is tested each time before you can know that it's
equivalent to a C-style `switch`.

IOW, I consider rewriting the `cond` to use `pcase` to be a form of
"common sub-expression elimination", or reduction of copy&paste.

I think rewriting those pcase uses into cond+eq would be equivalent for
me to rewriting dolists into while+pop loops (where you similarly can't
tell whether the loop advances by a single element each time without
consulting the loop body looking for all assignments to the temp var on
which the iteration is performed).

I prefer pcase to cl-case but I even much more strongly prefer cl-case
over cond+eq.

> My favorite is imap.el, which does something like the above in 3
> nested levels.  I will spare you the code, you can look it up.

We clearly have very different programming backgrounds: to me the "case
style" is much nicer and easier to read, closer to what I think in
my head, whereas the "cond+eq style" is like a "assembly-language"
version of the same.

> Is it because people are too lazy to write (eq a b) as part of 'cond'?
> Or is there something else I'm missing?

As a researcher in programming languages, I consider that my job is to
design and bring to practitioners tools that let them write in ways that
are closer to how they think than to how the machine thinks (while
still being able to turn it into something the machine can run efficiently).

The above argument of "too lazy to write ..." reminds me of the
resistance against the introduction of "high-level languages" instead of
the use of assembly language.

> You may wonder why I'm bothered by such uses.  It's because people are
> evidently confused by 'pcase's arcane syntax, and therefore produce
> obfuscated code even in the simple usage.  For example:
>
> apropos.el:
>
>       (pcase (car-safe x)
>       ;; (autoload (push (cdr x) autoloads))
>       (`require (push (cdr x) requires))
>       (`provide (push (cdr x) provides))
>         (`t nil) ; Skip "was an autoload" entries.
>         ;; FIXME: Print information about each individual method: both
>         ;; its docstring and specializers (bug#21422).
>         (`cl-defmethod (push (cadr x) provides))
>       (_ (push (or (cdr-safe x) x) symbols))))
>
> (Quick: what's the difference between `require and 'require in this
> case?)

Same difference as between 'require and `require in normal Elisp code.
Why is that a problem in pcase and not in the rest of Elisp?

[ The story behind this is that the first version of pcase
  only supported the ` syntax and the syntax was added to provide
  a "target" for the expansion of ` when ` was made into
  a pcase-macro rather than a core pcase functionality.  ]

> easy-mmode.el:
>
>       (pcase keyw
>       (`:group (setq group (nconc group (list :group (pop keys)))))
>       (`:global (setq keys (cdr keys)))
>       (_ (push keyw extra-keywords) (push (pop keys) extra-keywords))))
>
> (Aren't keywords supposed to be self-quoting? then why they are
> explicitly quoted?)

Same reason why keyaords might be (back)quoted in some Elisp code?
[ Or maybe also because keywords were originally not self-quoting in
  pcase macros?  ]

> So I think we should begin by rewriting all of such uses as simple
> 'cond', and ask contributors not to use 'pcase' where a simple 'cond'
> will do.

>From where I stand it would be a very sad step backward.
Rewriting those to use ' quoting (or no quoting at all when not needed)
is fine (tho not important), but the cond form is clearly inferior IMO.


        Stefan




reply via email to

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