GNU bug report logs -
#27584
26.0.50; alist-get: Add optional arg TESTFN
Previous Next
Reported by: Tino Calancha <tino.calancha <at> gmail.com>
Date: Wed, 5 Jul 2017 03:24:02 UTC
Severity: wishlist
Found in version 26.0.50
Done: Tino Calancha <tino.calancha <at> gmail.com>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
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?
This bug report was last modified 7 years and 352 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.