Created
November 20, 2015 11:45
-
-
Save spacebat/6613f07b5a3d5c5c9f8b to your computer and use it in GitHub Desktop.
Sketch of a let-alist.el alternative
This file contains hidden or 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
| (defconst my/lookup-extra-handlers nil) | |
| (cl-defun my/lookup (map key &key default test type) | |
| (typecase map | |
| (list | |
| (case type | |
| (plist (getf map key default)) | |
| (list (nth key map)) | |
| (t (let ((cell (assoc key map))) | |
| (if cell | |
| (cdr cell) | |
| default))))) | |
| (vector | |
| (aref map key)) | |
| (hash-table | |
| (gethash key map default)) | |
| (t | |
| (let ((handler (cdr (assq (type-of map) my/lookup-extra-handlers)))) | |
| (if handler | |
| (funcall handler map key default) | |
| (error "Unsupported map type %s" (type-of map))))))) | |
| (cl-defmacro with-lookup ((map &key name test type) &body body) | |
| (let ((map-sym (gensym "map")) | |
| reader-name | |
| (test-sym (and test (gensym "test"))) | |
| (type-sym (and type (gensym "type"))) | |
| result) | |
| (setf reader-name | |
| (cond | |
| ((symbolp map) | |
| (or name map)) | |
| (t | |
| (unless name | |
| (error "Either map must be a symbol or name is provided")) | |
| name))) | |
| (setf result | |
| `(labels ((,reader-name (key &optional default) | |
| (my/lookup ,map key | |
| :default default | |
| ,@(when test-sym | |
| `(:test ,test-sym)) | |
| ,@(when type-sym | |
| `(:type ,type-sym))))) | |
| ,@body)) | |
| (let ((bindings (append (when test-sym | |
| `(test-sym test)) | |
| (when type-sym | |
| `(type-sym type))))) | |
| (when bindings | |
| (setf result `(let (,@bindings) ,result)))) | |
| result)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment