unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#66509: 29.1.50; let-alist should support numeric indexing
@ 2023-10-12 22:03 Spencer Baugh
  2023-10-12 22:04 ` Spencer Baugh
  0 siblings, 1 reply; 7+ messages in thread
From: Spencer Baugh @ 2023-10-12 22:03 UTC (permalink / raw)
  To: 66509


It would be nice if let-alist supported indexing.  So if my alist
contained lists in some places, instead of writing:

(let-alist alist
  (let-alist (nth 0 .a)
    (let-alist (nth 3 .b)
       .c)))

I could instead write:

(let-alist alist
  .a.0.b.3.c)

A patch which does this to follow.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#66509: 29.1.50; let-alist should support numeric indexing
  2023-10-12 22:03 bug#66509: 29.1.50; let-alist should support numeric indexing Spencer Baugh
@ 2023-10-12 22:04 ` Spencer Baugh
  2024-09-10 23:22   ` Stefan Kangas
  0 siblings, 1 reply; 7+ messages in thread
From: Spencer Baugh @ 2023-10-12 22:04 UTC (permalink / raw)
  To: 66509

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: 0001-Support-numeric-indexing-in-let-alist.patch --]
[-- Type: text/x-patch, Size: 3579 bytes --]

From 28e52a343f72dddd991cafd23fea910cc5f64ac5 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh@janestreet.com>
Date: Thu, 12 Oct 2023 18:01:46 -0400
Subject: [PATCH] Support numeric indexing in let-alist

let-alist is very useful.  But sometimes an alist contains a list in
the middle, which contains yet more alists.  Previously, this was
somewhat painful to deal with, and required something like:

(let-alist alist
  (let-alist (nth 0 .a)
    (let-alist (nth 3 .b)
       .c)))

Now, the following works:

(let-alist alist
  .a.0.b.3.c)

* lisp/emacs-lisp/let-alist.el (let-alist--access-sexp): Properly
parse numbers.
(let-alist--list-to-sexp): Use nth to handle numbers.
(let-alist): Update docs.
---
 lisp/emacs-lisp/let-alist.el | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/lisp/emacs-lisp/let-alist.el b/lisp/emacs-lisp/let-alist.el
index d9ad46b2af7..de7c087bf2a 100644
--- a/lisp/emacs-lisp/let-alist.el
+++ b/lisp/emacs-lisp/let-alist.el
@@ -36,22 +36,23 @@
 ;; symbol inside body is let-bound to their cdrs in the alist.  Dotted
 ;; symbol is any symbol starting with a `.'.  Only those present in
 ;; the body are let-bound and this search is done at compile time.
+;; A number will result in a list index.
 ;;
 ;; For instance, the following code
 ;;
 ;;   (let-alist alist
-;;     (if (and .title .body)
+;;     (if (and .title.0 .body)
 ;;         .body
 ;;       .site
 ;;       .site.contents))
 ;;
 ;; essentially expands to
 ;;
-;;   (let ((.title (cdr (assq 'title alist)))
+;;   (let ((.title.0 (nth 0 (cdr (assq 'title alist))))
 ;;         (.body  (cdr (assq 'body alist)))
 ;;         (.site  (cdr (assq 'site alist)))
 ;;         (.site.contents (cdr (assq 'contents (cdr (assq 'site alist))))))
-;;     (if (and .title .body)
+;;     (if (and .title.0 .body)
 ;;         .body
 ;;       .site
 ;;       .site.contents))
@@ -93,14 +94,17 @@ let-alist--access-sexp
     (if (string-match "\\`\\." name)
         clean
       (let-alist--list-to-sexp
-       (mapcar #'intern (nreverse (split-string name "\\.")))
+       (mapcar #'read (nreverse (split-string name "\\.")))
        variable))))
 
 (defun let-alist--list-to-sexp (list var)
   "Turn symbols LIST into recursive calls to `cdr' `assq' on VAR."
-  `(cdr (assq ',(car list)
-              ,(if (cdr list) (let-alist--list-to-sexp (cdr list) var)
-                 var))))
+  (let ((sym (car list))
+        (rest (if (cdr list) (let-alist--list-to-sexp (cdr list) var)
+                 var)))
+    (cond
+     ((numberp sym) `(nth ,sym ,rest))
+     (t `(cdr (assq ',sym ,rest))))))
 
 (defun let-alist--remove-dot (symbol)
   "Return SYMBOL, sans an initial dot."
@@ -116,22 +120,23 @@ let-alist
   "Let-bind dotted symbols to their cdrs in ALIST and execute BODY.
 Dotted symbol is any symbol starting with a `.'.  Only those present
 in BODY are let-bound and this search is done at compile time.
+A number will result in a list index.
 
 For instance, the following code
 
   (let-alist alist
-    (if (and .title .body)
+    (if (and .title.0 .body)
         .body
       .site
       .site.contents))
 
 essentially expands to
 
-  (let ((.title (cdr (assq \\='title alist)))
+  (let ((.title (nth 0 (cdr (assq \\='title alist))))
         (.body  (cdr (assq \\='body alist)))
         (.site  (cdr (assq \\='site alist)))
         (.site.contents (cdr (assq \\='contents (cdr (assq \\='site alist))))))
-    (if (and .title .body)
+    (if (and .title.0 .body)
         .body
       .site
       .site.contents))
-- 
2.39.3






^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#66509: 29.1.50; let-alist should support numeric indexing
  2023-10-12 22:04 ` Spencer Baugh
@ 2024-09-10 23:22   ` Stefan Kangas
  2024-09-17  2:07     ` Artur Malabarba
  0 siblings, 1 reply; 7+ messages in thread
From: Stefan Kangas @ 2024-09-10 23:22 UTC (permalink / raw)
  To: Spencer Baugh; +Cc: Artur Malabarba, 66509

Artur, do you have any thoughts on the below patch?

Spencer Baugh <sbaugh@janestreet.com> writes:

> From 28e52a343f72dddd991cafd23fea910cc5f64ac5 Mon Sep 17 00:00:00 2001
> From: Spencer Baugh <sbaugh@janestreet.com>
> Date: Thu, 12 Oct 2023 18:01:46 -0400
> Subject: [PATCH] Support numeric indexing in let-alist
>
> let-alist is very useful.  But sometimes an alist contains a list in
> the middle, which contains yet more alists.  Previously, this was
> somewhat painful to deal with, and required something like:
>
> (let-alist alist
>   (let-alist (nth 0 .a)
>     (let-alist (nth 3 .b)
>        .c)))
>
> Now, the following works:
>
> (let-alist alist
>   .a.0.b.3.c)
>
> * lisp/emacs-lisp/let-alist.el (let-alist--access-sexp): Properly
> parse numbers.
> (let-alist--list-to-sexp): Use nth to handle numbers.
> (let-alist): Update docs.
> ---
>  lisp/emacs-lisp/let-alist.el | 25 +++++++++++++++----------
>  1 file changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/lisp/emacs-lisp/let-alist.el b/lisp/emacs-lisp/let-alist.el
> index d9ad46b2af7..de7c087bf2a 100644
> --- a/lisp/emacs-lisp/let-alist.el
> +++ b/lisp/emacs-lisp/let-alist.el
> @@ -36,22 +36,23 @@
>  ;; symbol inside body is let-bound to their cdrs in the alist.  Dotted
>  ;; symbol is any symbol starting with a `.'.  Only those present in
>  ;; the body are let-bound and this search is done at compile time.
> +;; A number will result in a list index.
>  ;;
>  ;; For instance, the following code
>  ;;
>  ;;   (let-alist alist
> -;;     (if (and .title .body)
> +;;     (if (and .title.0 .body)
>  ;;         .body
>  ;;       .site
>  ;;       .site.contents))
>  ;;
>  ;; essentially expands to
>  ;;
> -;;   (let ((.title (cdr (assq 'title alist)))
> +;;   (let ((.title.0 (nth 0 (cdr (assq 'title alist))))
>  ;;         (.body  (cdr (assq 'body alist)))
>  ;;         (.site  (cdr (assq 'site alist)))
>  ;;         (.site.contents (cdr (assq 'contents (cdr (assq 'site alist))))))
> -;;     (if (and .title .body)
> +;;     (if (and .title.0 .body)
>  ;;         .body
>  ;;       .site
>  ;;       .site.contents))
> @@ -93,14 +94,17 @@ let-alist--access-sexp
>      (if (string-match "\\`\\." name)
>          clean
>        (let-alist--list-to-sexp
> -       (mapcar #'intern (nreverse (split-string name "\\.")))
> +       (mapcar #'read (nreverse (split-string name "\\.")))
>         variable))))
>
>  (defun let-alist--list-to-sexp (list var)
>    "Turn symbols LIST into recursive calls to `cdr' `assq' on VAR."
> -  `(cdr (assq ',(car list)
> -              ,(if (cdr list) (let-alist--list-to-sexp (cdr list) var)
> -                 var))))
> +  (let ((sym (car list))
> +        (rest (if (cdr list) (let-alist--list-to-sexp (cdr list) var)
> +                 var)))
> +    (cond
> +     ((numberp sym) `(nth ,sym ,rest))
> +     (t `(cdr (assq ',sym ,rest))))))
>
>  (defun let-alist--remove-dot (symbol)
>    "Return SYMBOL, sans an initial dot."
> @@ -116,22 +120,23 @@ let-alist
>    "Let-bind dotted symbols to their cdrs in ALIST and execute BODY.
>  Dotted symbol is any symbol starting with a `.'.  Only those present
>  in BODY are let-bound and this search is done at compile time.
> +A number will result in a list index.
>
>  For instance, the following code
>
>    (let-alist alist
> -    (if (and .title .body)
> +    (if (and .title.0 .body)
>          .body
>        .site
>        .site.contents))
>
>  essentially expands to
>
> -  (let ((.title (cdr (assq \\='title alist)))
> +  (let ((.title (nth 0 (cdr (assq \\='title alist))))
>          (.body  (cdr (assq \\='body alist)))
>          (.site  (cdr (assq \\='site alist)))
>          (.site.contents (cdr (assq \\='contents (cdr (assq \\='site alist))))))
> -    (if (and .title .body)
> +    (if (and .title.0 .body)
>          .body
>        .site
>        .site.contents))





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#66509: 29.1.50; let-alist should support numeric indexing
  2024-09-10 23:22   ` Stefan Kangas
@ 2024-09-17  2:07     ` Artur Malabarba
  2024-09-19  1:56       ` Stefan Kangas
  0 siblings, 1 reply; 7+ messages in thread
From: Artur Malabarba @ 2024-09-17  2:07 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: Spencer Baugh, 66509

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

Hi all,

The patch looks good.
Stefan, would you mind applying it? (It'll take a while for me to get
everything configured.)

best,
Artur


On Tue, 10 Sept 2024 at 20:22, Stefan Kangas <stefankangas@gmail.com> wrote:

> Artur, do you have any thoughts on the below patch?
>
> Spencer Baugh <sbaugh@janestreet.com> writes:
>
> > From 28e52a343f72dddd991cafd23fea910cc5f64ac5 Mon Sep 17 00:00:00 2001
> > From: Spencer Baugh <sbaugh@janestreet.com>
> > Date: Thu, 12 Oct 2023 18:01:46 -0400
> > Subject: [PATCH] Support numeric indexing in let-alist
> >
> > let-alist is very useful.  But sometimes an alist contains a list in
> > the middle, which contains yet more alists.  Previously, this was
> > somewhat painful to deal with, and required something like:
> >
> > (let-alist alist
> >   (let-alist (nth 0 .a)
> >     (let-alist (nth 3 .b)
> >        .c)))
> >
> > Now, the following works:
> >
> > (let-alist alist
> >   .a.0.b.3.c)
> >
> > * lisp/emacs-lisp/let-alist.el (let-alist--access-sexp): Properly
> > parse numbers.
> > (let-alist--list-to-sexp): Use nth to handle numbers.
> > (let-alist): Update docs.
> > ---
> >  lisp/emacs-lisp/let-alist.el | 25 +++++++++++++++----------
> >  1 file changed, 15 insertions(+), 10 deletions(-)
> >
> > diff --git a/lisp/emacs-lisp/let-alist.el b/lisp/emacs-lisp/let-alist.el
> > index d9ad46b2af7..de7c087bf2a 100644
> > --- a/lisp/emacs-lisp/let-alist.el
> > +++ b/lisp/emacs-lisp/let-alist.el
> > @@ -36,22 +36,23 @@
> >  ;; symbol inside body is let-bound to their cdrs in the alist.  Dotted
> >  ;; symbol is any symbol starting with a `.'.  Only those present in
> >  ;; the body are let-bound and this search is done at compile time.
> > +;; A number will result in a list index.
> >  ;;
> >  ;; For instance, the following code
> >  ;;
> >  ;;   (let-alist alist
> > -;;     (if (and .title .body)
> > +;;     (if (and .title.0 .body)
> >  ;;         .body
> >  ;;       .site
> >  ;;       .site.contents))
> >  ;;
> >  ;; essentially expands to
> >  ;;
> > -;;   (let ((.title (cdr (assq 'title alist)))
> > +;;   (let ((.title.0 (nth 0 (cdr (assq 'title alist))))
> >  ;;         (.body  (cdr (assq 'body alist)))
> >  ;;         (.site  (cdr (assq 'site alist)))
> >  ;;         (.site.contents (cdr (assq 'contents (cdr (assq 'site
> alist))))))
> > -;;     (if (and .title .body)
> > +;;     (if (and .title.0 .body)
> >  ;;         .body
> >  ;;       .site
> >  ;;       .site.contents))
> > @@ -93,14 +94,17 @@ let-alist--access-sexp
> >      (if (string-match "\\`\\." name)
> >          clean
> >        (let-alist--list-to-sexp
> > -       (mapcar #'intern (nreverse (split-string name "\\.")))
> > +       (mapcar #'read (nreverse (split-string name "\\.")))
> >         variable))))
> >
> >  (defun let-alist--list-to-sexp (list var)
> >    "Turn symbols LIST into recursive calls to `cdr' `assq' on VAR."
> > -  `(cdr (assq ',(car list)
> > -              ,(if (cdr list) (let-alist--list-to-sexp (cdr list) var)
> > -                 var))))
> > +  (let ((sym (car list))
> > +        (rest (if (cdr list) (let-alist--list-to-sexp (cdr list) var)
> > +                 var)))
> > +    (cond
> > +     ((numberp sym) `(nth ,sym ,rest))
> > +     (t `(cdr (assq ',sym ,rest))))))
> >
> >  (defun let-alist--remove-dot (symbol)
> >    "Return SYMBOL, sans an initial dot."
> > @@ -116,22 +120,23 @@ let-alist
> >    "Let-bind dotted symbols to their cdrs in ALIST and execute BODY.
> >  Dotted symbol is any symbol starting with a `.'.  Only those present
> >  in BODY are let-bound and this search is done at compile time.
> > +A number will result in a list index.
> >
> >  For instance, the following code
> >
> >    (let-alist alist
> > -    (if (and .title .body)
> > +    (if (and .title.0 .body)
> >          .body
> >        .site
> >        .site.contents))
> >
> >  essentially expands to
> >
> > -  (let ((.title (cdr (assq \\='title alist)))
> > +  (let ((.title (nth 0 (cdr (assq \\='title alist))))
> >          (.body  (cdr (assq \\='body alist)))
> >          (.site  (cdr (assq \\='site alist)))
> >          (.site.contents (cdr (assq \\='contents (cdr (assq \\='site
> alist))))))
> > -    (if (and .title .body)
> > +    (if (and .title.0 .body)
> >          .body
> >        .site
> >        .site.contents))
>

[-- Attachment #2: Type: text/html, Size: 5891 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#66509: 29.1.50; let-alist should support numeric indexing
  2024-09-17  2:07     ` Artur Malabarba
@ 2024-09-19  1:56       ` Stefan Kangas
  2024-09-19  5:56         ` Eli Zaretskii
  0 siblings, 1 reply; 7+ messages in thread
From: Stefan Kangas @ 2024-09-19  1:56 UTC (permalink / raw)
  To: Artur Malabarba; +Cc: Spencer Baugh, 66509-done

Version: 31.1

Artur Malabarba <arturmalabarba@gmail.com> writes:

> Hi all,
>
> The patch looks good.

Thanks.

> Stefan, would you mind applying it? (It'll take a while for me to get
> everything configured.)

Pushed to master (commit ae4171efdc6).

I'm therefore closing this bug report.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#66509: 29.1.50; let-alist should support numeric indexing
  2024-09-19  1:56       ` Stefan Kangas
@ 2024-09-19  5:56         ` Eli Zaretskii
  2024-09-27  7:15           ` Stefan Kangas
  0 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2024-09-19  5:56 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: sbaugh, stefankangas, 66509

> Resent-To: bug-gnu-emacs@gnu.org
> Cc: Spencer Baugh <sbaugh@janestreet.com>, 66509-done@debbugs.gnu.org
> From: Stefan Kangas <stefankangas@gmail.com>
> Date: Wed, 18 Sep 2024 18:56:37 -0700
> 
> Version: 31.1
> 
> Artur Malabarba <arturmalabarba@gmail.com> writes:
> 
> > Hi all,
> >
> > The patch looks good.
> 
> Thanks.
> 
> > Stefan, would you mind applying it? (It'll take a while for me to get
> > everything configured.)
> 
> Pushed to master (commit ae4171efdc6).
> 
> I'm therefore closing this bug report.

Thanks, but could we perhaps have tests for this new functionality?





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#66509: 29.1.50; let-alist should support numeric indexing
  2024-09-19  5:56         ` Eli Zaretskii
@ 2024-09-27  7:15           ` Stefan Kangas
  0 siblings, 0 replies; 7+ messages in thread
From: Stefan Kangas @ 2024-09-27  7:15 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: sbaugh, 66509

reopen 66509
thanks

>> Pushed to master (commit ae4171efdc6).
>>
>> I'm therefore closing this bug report.

I'm reopening this bug report, based on this request from Robert Pluim:

> Would it be possible to update the elisp manual as well (and maybe add
> an entry to NEWS)?

I think that should be done also, so I'm reopening the bug to track that
work.  Spencer, do you think you could you please address it?

Bonus points for adding tests, as requested by Eli.

Thanks in advance.





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-09-27  7:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-12 22:03 bug#66509: 29.1.50; let-alist should support numeric indexing Spencer Baugh
2023-10-12 22:04 ` Spencer Baugh
2024-09-10 23:22   ` Stefan Kangas
2024-09-17  2:07     ` Artur Malabarba
2024-09-19  1:56       ` Stefan Kangas
2024-09-19  5:56         ` Eli Zaretskii
2024-09-27  7:15           ` Stefan Kangas

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).