Re: Making alistp matching plistp requirements
tpeplt <[email protected]>
| Newsgroups | gmane.emacs.help |
|---|---|
| Message-ID | <[email protected]> |
Heime <[email protected]> writes: > On Monday, April 13th, 2026 at 10:55 AM, tpeplt <[email protected]> wrote: > >> Heime <[email protected]> writes: >> >> > On Monday, April 13th, 2026 at 9:59 AM, tpeplt <[email protected]> wrote: >> > >> >> >> >> Here is a simple definition that does not check the contents >> >> of the items in the alist: >> >> >> >> (defun alistp (obj-list) >> >> "Determine whether OBJ-LIST is an association list. >> >> This function definition says that an empty list is not >> >> an association list." >> >> (when (and obj-list (proper-list-p obj-list)) >> >> (cl-every #'consp obj-list))) >> > >> > Emacs Lisp plistp allows nil as both keys and values. >> > Have been thinking of keeping with same idea to accept >> > nil. >> > >> >> That is a simple change to the definition, above: >> >> (defun alistp (obj-list) >> "Determine whether OBJ-LIST is an association list." >> (when (proper-list-p obj-list) >> (cl-every #'consp obj-list))) >> >> Be aware that you may need code to distinguish between a >> value set to nil in an alist and an empty alist: >> >> (alist-get 'a '((a . nil))) >> ;;=> nil >> (alist-get 'a '()) >> ;;=> nil > > Have come up with this > > (defun lana-alistp (object) > (declare (pure t) (side-effect-free error-free)) > (cond ((atom object) (eq object nil)) > (t (and (consp (car object)) > (lana-alistp (cdr object)))))) > > How do you think this compares with your version? > So long as your alist is not too long, this should work. Emacs has a nested-call limit that you should be aware of, see ‘max-lisp-eval-depth’ in (info "(elisp) Eval"). Here is what a trace of your function looks like: (lana-alistp '((a . b) (c . d) (1 . 2) (f . g))) => 1 -> (lana-alistp ((a . b) (c . d) (1 . 2) (f . g))) | 2 -> (lana-alistp ((c . d) (1 . 2) (f . g))) | | 3 -> (lana-alistp ((1 . 2) (f . g))) | | | 4 -> (lana-alistp ((f . g))) | | | | 5 -> (lana-alistp nil) | | | | 5 <- lana-alistp: t | | | 4 <- lana-alistp: t | | 3 <- lana-alistp: t | 2 <- lana-alistp: t 1 <- lana-alistp: t Here is an example of a long alist (2000 pairs): (defvar long-list (loop for i upto 2000 collect '(a . b))) When (lana-alistp long-list) is evaluated, Emacs reports: Entering debugger... cl-prin1: (excessive-lisp-nesting 1622) cl-prin1: (error "Lisp nesting exceeds ‘max-lisp-eval-depth’") [1599 times] The definition of ‘alistp’ using ‘cl-every’ will return t when given ‘long-list’ as its argument. -- The lyf so short, the craft so long to lerne. - Geoffrey Chaucer, The Parliament of Birds.