Skip to content

Instantly share code, notes, and snippets.

Last active October 9, 2015 10:05
What would you like to do?
A better alist macro
;;; 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 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))
(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 into an alist lookup on foo.
This macro works on nested"
(declare (indent 0))
,@(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