all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Thien-Thi Nguyen <ttn@gnu.org>
To: Stefan Monnier <monnier@IRO.UMontreal.CA>
Cc: emacs-devel@gnu.org
Subject: Re: EXPVAL in pcase-defmacro docstrings
Date: Thu, 31 May 2018 16:56:38 +0200	[thread overview]
Message-ID: <87y3fzx49l.fsf@gnuvola.org> (raw)
In-Reply-To: <jwvfu29xs2s.fsf-monnier+emacs@gnu.org> (Stefan Monnier's message of "Wed, 30 May 2018 08:28:29 -0400")

[-- Attachment #1: Type: text/plain, Size: 4582 bytes --]


() Stefan Monnier <monnier@IRO.UMontreal.CA>
() Wed, 30 May 2018 08:28:29 -0400

   I think this change is misguided:

   - When reading source code, you get things like:

         (pcase-defmacro radix-tree-leaf (vpat)
           "Build a `pcase' pattern that matches radix-tree leaf EXPVAL.
         VPAT is a `pcase' pattern to extract the value."

     where the EXPVAL comes out of nowhere

   - The wording "matches radix-tree leaf EXPVAL" makes it sound
     like the reader is already familiar with EXPVAL and that we
     know already that it's a radix-tree leaf, whereas the
     pattern will have to check if EXPVAL is such a leaf.

Yes.  That is awkward, when reading the source code.  Thanks for
pointing it out; i was focusing on the aggregated docstring for
that change.  For docstrings where it makes sense to use EXPVAL
(maybe not this one), how about we add a small comment pointing
to the EXPVAL convention?  That way, we retain consistency in
the presentation (for ‘C-h f pcase RET’), and give a clue to
people who read source code.

I say "maybe" because, in trying to better understand the
operation of ‘radix-tree-leaf’, i found this comment puzzling:

    ;; FIXME: We'd like to use a negative pattern (not consp),
    ;; but pcase doesn't support it.  Using `atom' works but
    ;; generates sub-optimal code.
    `(or `(t . ,,vpat) (and (pred atom) ,vpat))))

Does that mean we'd want a hypothetical ‘(pred (not consp))’ if
such a construct were supported by ‘pcase’?

Another question i have concerns ‘(t . ...)’.  My understanding
is that in a structural pattern (that begins with backquote), a
symbol represents itself.  However, IIUC the car of the nodes is
always a string.  So this subpattern never matches.

Experimenting in *scratch*, i see:

 (let ((tr radix-tree-empty)
       sub)
   (setq tr (radix-tree-insert tr "all" 0)
         tr (radix-tree-insert tr "abc" 99)
         tr (radix-tree-insert tr "abx" 2)
         sub (radix-tree-subtree tr "a"))
   (list :sub sub
         :etc (pcase sub
                ((radix-tree-leaf v) v))))
 =>
 (:sub
  (("ll" . 0)
   ("b"
    ("c" . 99)
    ("x" . 2)))
  :etc nil)
 
However, if i define ‘radix-tree-leaf-NEW’ as follows:

 (eval-and-compile
   (pcase-defmacro radix-tree-leaf-NEW (vpat)
     `(or `(,_ . ,,vpat)
          (and (pred atom)
               ,vpat))))

replacing ‘t’ w/ ‘,_’ (comma underscore) to "match anything", i
see instead:

 (let ((tr radix-tree-empty)
       sub)
   (setq tr (radix-tree-insert tr "all" 0)
         tr (radix-tree-insert tr "abc" 99)
         tr (radix-tree-insert tr "abx" 2)
         sub (radix-tree-subtree tr "a"))
   (list :sub sub
         :etc (pcase sub
                ((radix-tree-leaf-NEW v) v))))
 =>
 (:sub
  (("ll" . 0)
   ("b"
    ("c" . 99)
    ("x" . 2)))
  :etc
  (("b"
    ("c" . 99)
    ("x" . 2))))

Thinking about this a bit more, i suppose the comment makes
sense if the intention of using ‘t’ is to never match.  Since
‘pcase’ supports lambda expressions for the ‘pred’ pattern,
we can use one directly:

 (pred (lambda (x) (not (consp x))))

and then simplify the definition to something like:

 (eval-and-compile
   (pcase-defmacro radix-tree-leaf-NEW-2 (vpat)
     `(and (pred (lambda (x)
                   (not (consp x))))
           ,vpat)))

Another idea is to make ‘pcase’ support a new core pattern, say
"npred", which would be similar to ‘pred’ but invert the result
of the predicate it uses.  Here, it would be: ‘(npred consp)’.

If this interpretation is correct, i would also suggest another
change: from VPAT to VAR.  This would emphasize that VAR is the
usual vehicle for binding the leaf node "data" for use in the
clause's body forms.  (Maybe "usual" is stretching it -- i found
only one use of ‘radix-tree-leaf’ in the Emacs 26 repo.)  Using
VAR would be easier to document, too.

Anyway, the documentation can say "VAR can also be a pcase
pattern", so as not preclude more complex usage.  WDYT?

I'll respond to the remaining points in the next mail.

-- 
Thien-Thi Nguyen -----------------------------------------------
 (defun responsep (query)               ; (2018) Software Libero
   (pcase (context query)               ;       = Dissenso Etico
     (`(technical ,ml) (correctp ml))
     ...))                              748E A0E8 1CB8 A748 9BFA
--------------------------------------- 6CE4 6703 2224 4C80 7502


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

  reply	other threads:[~2018-05-31 14:56 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-30 12:28 EXPVAL in pcase-defmacro docstrings Stefan Monnier
2018-05-31 14:56 ` Thien-Thi Nguyen [this message]
2018-06-04 14:43   ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y3fzx49l.fsf@gnuvola.org \
    --to=ttn@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@IRO.UMontreal.CA \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.