Skip to content

Instantly share code, notes, and snippets.

@hiredman
Last active October 13, 2022 20:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiredman/b2096b04927a9c9db480c39806dac297 to your computer and use it in GitHub Desktop.
Save hiredman/b2096b04927a9c9db480c39806dac297 to your computer and use it in GitHub Desktop.
(defmacro let-macro
([bindings body]
(let [names (map first bindings)]
`(let-macro ~(eval `(letfn ~bindings ~(into {} (map (fn [n] [(list 'quote n) n])) names)))
~identity
~body)))
([bindings k body]
(cond (and (seq? body)
(symbol? (first body))
(contains? bindings (first body)))
`(let-macro ~bindings ~k ~(apply (get bindings (first body)) (rest body)))
(and (seq? body)
(symbol? (first body))
(= "quote" (name (first body))))
body
(and (or (vector? body) (seq? body)) (seq body))
`(let-macro ~bindings
~(partial (fn f [i o v]
(if (seq i)
`(let-macro ~bindings
~(partial f (rest i) (conj o v))
~(first i))
(do
(prn "body" body (conj o v))
(k ((if (vector? body) identity seq) (conj o v))))))
(rest body)
[])
~(first body))
(and (coll? body) (not (record? body)))
`(let-macro ~bindings ~(fn [v]
(prn "v" v)
(k (into (empty body) v))) ~(seq body))
:else
(k body))))
@hiredman
Copy link
Author

user=> '(let-macro [(f [] nil)] {:a (f)})
(let-macro [(f [] nil)] {:a (f)})
user=> (macroexpand-1 *1)
(user/let-macro {f #object[user$eval196$f__197 0x56ccd751 "user$eval196$f__197@56ccd751"]} #object[clojure.core$identity 0x17ae7628 "clojure.core$identity@17ae7628"] {:a (f)})
user=> (macroexpand-1 *1)
(user/let-macro {f #object[user$eval196$f__197 0x56ccd751 "user$eval196$f__197@56ccd751"]} #object[user$let_macro$fn__178 0x72ed9aad "user$let_macro$fn__178@72ed9aad"] ([:a (f)]))
user=> (macroexpand-1 *1)
(user/let-macro {f #object[user$eval196$f__197 0x56ccd751 "user$eval196$f__197@56ccd751"]} #object[clojure.core$partial$fn__5910 0x1869f114 "clojure.core$partial$fn__5910@1869f114"] [:a (f)])
user=> (macroexpand-1 *1)
(user/let-macro {f #object[user$eval196$f__197 0x56ccd751 "user$eval196$f__197@56ccd751"]} #object[clojure.core$partial$fn__5910 0x37a64f9d "clojure.core$partial$fn__5910@37a64f9d"] :a)
user=> (macroexpand-1 *1)
(user/let-macro {f #object[user$eval196$f__197 0x56ccd751 "user$eval196$f__197@56ccd751"]} #object[clojure.core$partial$fn__5910 0x5e3a39cd "clojure.core$partial$fn__5910@5e3a39cd"] (f))
user=> (macroexpand-1 *1)
(user/let-macro {f #object[user$eval196$f__197 0x56ccd751 "user$eval196$f__197@56ccd751"]} #object[clojure.core$partial$fn__5910 0x5e3a39cd "clojure.core$partial$fn__5910@5e3a39cd"] nil)
user=> (macroexpand-1 *1)
{:a nil}
user=>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment