A better alist macro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; with-alist-access.el --- a better alist macro | |
;; This is free and unencumbered software released into the public domain. | |
;;; Commentary: | |
;; Usage example: | |
;; (let ((student '((id . 1332412) | |
;; (name . ((first . "Student") | |
;; (last . "Example"))))) | |
;; (teacher '((subject . math) | |
;; (full-name . "Teacher Example")))) | |
;; (with-alist-access | |
;; (list student.name.first teacher.full-name))) | |
;; Result: | |
;; => ("Student" "Teacher Example") | |
;;; Code: | |
(require 'cl-lib) | |
(defun with-alist-access--transform-symbol (symbol) | |
"Convert a symbol containing dots into an alist lookup." | |
(let ((split (mapcar #'intern (split-string (symbol-name symbol) "\\.")))) | |
(if (= 1 (length split)) | |
symbol | |
(cl-reduce (lambda (object key) | |
`(cdr (assq ',key ,object))) split)))) | |
(defun with-alist-access--transform-sexp (sexp) | |
"Transform a single s-expression for `with-alist-access'." | |
(cons (car sexp) | |
(cl-loop for arg in (cdr sexp) collect | |
(cl-typecase arg | |
(list (with-alist-access--transform-sexp arg)) | |
(symbol (with-alist-access--transform-symbol arg)) | |
(otherwise arg))))) | |
(defmacro with-alist-access (&rest body) | |
"Convert all variables of the form foo.bar into an alist lookup on foo. | |
This macro works on nested" | |
(declare (indent 0)) | |
`(progn | |
,@(mapcar #'with-alist-access--transform-sexp body))) | |
(provide 'with-alist-access) | |
;;; with-alist-access.el ends here |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment