-
Notifications
You must be signed in to change notification settings - Fork 0
/
let+.el
42 lines (37 loc) · 1.21 KB
/
let+.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
;;; let+.el --- Let everything -*- lexical-binding: t -*-
(mapc #'require
[cl-macs ; `cl-labels'
seq]) ; `seq-let'
;;; NOTE: Normally you should use this with (eval-when-compile (require 'let+)).
(defmacro let+ (BINDINGS &rest BODY)
"Locally bind variables and procedures and pattern-match sequences, then evaluate BODY.
Imagine BINDINGS as a big `setf' body that does the right thing with lists, functions, etc.
Example:
\(let+ ((a b) [1 2]
\foo ((x y) (+ x y)))
\(foo a b))
;=> 3"
(declare (indent 1))
(cl-labels
((sublet (var val)
;; Pattern-match to make the right kind of binding.
(cond
;; Sequence
((sequencep var)
`(seq-let ,var ,val))
;; Procedure
((and (consp val)
(listp (car val))
`(cl-labels ((,var . ,val)))))
;; Variable
(t
`(let ((,var ,val))))))
(combind (bindings)
;; String all the bindings together.
(if bindings
(seq-let (var val &rest brest) bindings
(let ((sublet (sublet var val)))
(append sublet `(,(combind brest)))))
`(progn . ,BODY))))
(combind BINDINGS)))
(provide 'let+)