[Top][All Lists]

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

bug#27584: 26.0.50; alist-get: Add optional arg TESTFN

From: Tino Calancha
Subject: bug#27584: 26.0.50; alist-get: Add optional arg TESTFN
Date: Sun, 9 Jul 2017 23:45:53 +0900 (JST)
User-agent: Alpine 2.20 (DEB 67 2015-01-07)

On Fri, 7 Jul 2017, Stefan Monnier wrote:

+  (declare (compiler-macro
+            (lambda (_)
+              `(pcase ,pred
+                 ('eq (assq ,key ,alist))
+                 ((or 'equal 'nil) (assoc ,key ,alist))
+                 ((guard (and (macroexp-const-p ,key) (eq ,pred 'eql)))
+                  (if (floatp ,key)
+                      (assoc ,key ,alist) (assq ,key ,alist)))
+                 (_ (assoc-default ,key ,alist ,pred nil 'full))))))

This replaces a call to the function with a chunk of code which does
`pcase`, which is not what we want: we want the `pcase` to be executed
during compilation and if we can't choose which branch to follow, then
we just keep the call unchanged (which is why, in my define-inline
example, the pcase was outside of `inline-quote`).
Thank you Stefan.  After playing a bit with this i'd like to
ask you something.

I rewrote it as follows:

  (declare (compiler-macro
            (lambda (form)
              (pcase pred
                (''eq `(assq ,key ,alist))
                ((or ''equal 'nil) `(assoc ,key ,alist))
                ((and (guard (macroexp-const-p key)) ''eql)
                 (if (floatp key)
                     `(assoc ,key ,alist) `(assq ,key ,alist)))
                (t form)))))

Apparently, it works as a charm:
*) For example, if i compile a file with content:
;; -*- lexical-binding: t; -*-

(defun run ()
    (assoc-predicate 999 '((1 . "a") (2 . "b")) 'eql))

*) tmp.elc contains, something like:
(defalias 'run #[0 "\300\301\236\207" [999 ((1 . "a") (2 . "b"))] 2])

**) But note what happens if the file contains:
;; -*- lexical-binding: t; -*-

(defun run ()
    (assoc-predicate (let ((x 999)) x) '((1 . "a") (2 . "b")) 'eql))

**) tmp.elc shows:
(defalias 'run #[0 "\300\301\211\262\302\303#\207" [assoc-predicate 999 ((1 . "a") (2 . "b")) eql] 4])

That is, in the pcase fails the condition:
(and (guard (macroexp-const-p key)) ''eql)
so that the compiler macro doesn't change the form.

But we know that:
(macroexp-const-p (let ((x 999)) x))
=> t

So, i would expect to **) compiles to similar code as *).

What is wrong with my assumptions?

reply via email to

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