Skip to content

Instantly share code, notes, and snippets.

@imrekoszo
Last active May 4, 2021 18:44
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 imrekoszo/5e5c007659264729fad26481206c2691 to your computer and use it in GitHub Desktop.
Save imrekoszo/5e5c007659264729fad26481206c2691 to your computer and use it in GitHub Desktop.
let% provides a mixed let + letfn macro. No mutual recursion tho
;; largely @emccue's implementation in https://clojurians-log.clojureverse.org/clojure on 2021-05-04
;; with a few fixes and adjustments
(defmacro let% [clauses & body]
(loop [clauses clauses
bindings []]
(if (empty? clauses)
`(let ~bindings ~@body)
(let [[fc & rcs] clauses]
(if (list? fc)
(recur rcs
(-> bindings
(conj (first fc))
(conj (cons `fn fc))))
(if (>= (count clauses) 2)
(recur (rest rcs)
(-> bindings
(conj fc)
(conj (second clauses))))
(throw (ex-info "Not enough clauses in let%" {:clauses clauses}))))))))
(let% [bar 1
(foo [x y z] [x y z])
{:keys [baz]} {:baz 2}
[_ _ qux] [0 0 3 4]]
(foo bar baz qux))
;; => [1 2 3]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment