From: Spencer Baugh <sbaugh@janestreet.com>
To: 66509@debbugs.gnu.org
Subject: bug#66509: 29.1.50; let-alist should support numeric indexing
Date: Thu, 12 Oct 2023 18:04:00 -0400 [thread overview]
Message-ID: <ier7cnr5whb.fsf@janestreet.com> (raw)
In-Reply-To: <iera5sn5wid.fsf@janestreet.com> (Spencer Baugh's message of "Thu, 12 Oct 2023 18:03:22 -0400")
[-- 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
next prev parent reply other threads:[~2023-10-12 22:04 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ier7cnr5whb.fsf@janestreet.com \
--to=sbaugh@janestreet.com \
--cc=66509@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.