From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: Replace trivial pcase occurrences in the Emacs sources Date: Wed, 24 Oct 2018 16:52:23 -0400 Message-ID: References: <20151216202605.GA3752@acm.fritz.box> <877fjrkpdf.fsf@fencepost.gnu.org> <56892334.4000106@yandex.ru> <8760zakb7q.fsf@fencepost.gnu.org> <56892BDA.6060103@dancol.org> <871t9yk98g.fsf@fencepost.gnu.org> <568936F0.3060505@yandex.ru> <87wprqitj5.fsf@fencepost.gnu.org> <56893C8C.3060200@yandex.ru> <87oad2irtd.fsf@fencepost.gnu.org> <5689456A.1010601@yandex.ru> <87egdy8tyz.fsf@fencepost.gnu.org> <56895FDE.4060406@yandex.ru> <8760za8r4a.fsf@fencepost.gnu.org> <87h9iunkcg.fsf@web.de> <87h8hc4xw2.fsf_-_@web.de> <83tvlcsnee.fsf@gnu.org> <87pnw037ar.fsf@web.de> <83ftwvs7y9.fsf@gnu.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1540414297 1678 195.159.176.226 (24 Oct 2018 20:51:37 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 24 Oct 2018 20:51:37 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Oct 24 22:51:32 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gFQ7o-0000JC-Aa for ged-emacs-devel@m.gmane.org; Wed, 24 Oct 2018 22:51:32 +0200 Original-Received: from localhost ([::1]:50300 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gFQ9u-0000jy-Lc for ged-emacs-devel@m.gmane.org; Wed, 24 Oct 2018 16:53:42 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:59704) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gFQ8x-0000gN-9C for emacs-devel@gnu.org; Wed, 24 Oct 2018 16:52:45 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gFQ8s-0002C2-3T for emacs-devel@gnu.org; Wed, 24 Oct 2018 16:52:41 -0400 Original-Received: from [195.159.176.226] (port=45579 helo=blaine.gmane.org) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gFQ8r-00027Q-PZ for emacs-devel@gnu.org; Wed, 24 Oct 2018 16:52:37 -0400 Original-Received: from list by blaine.gmane.org with local (Exim 4.84_2) (envelope-from ) id 1gFQ6e-0007K9-Oz for emacs-devel@gnu.org; Wed, 24 Oct 2018 22:50:20 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 109 Original-X-Complaints-To: usenet@blaine.gmane.org Cancel-Lock: sha1:wNkPeEeffWS975XZ1+IQo/jtOl4= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 195.159.176.226 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:230646 Archived-At: > (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