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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.