Created
April 16, 2012 09:32
-
-
Save ghoseb/2397263 to your computer and use it in GitHub Desktop.
Cut macro from SRFI-26 in Clojure
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
;;; http://srfi.schemers.org/srfi-26/srfi-26.html | |
(defn ^:private cut* | |
[[a f] form] | |
(cond | |
(nil? form) [a f] | |
(seq? (first form)) | |
(let [[arg-list xform] (cut* [[] '()] (first form))] | |
(recur [(reduce conj a arg-list) (concat f (list xform))] (next form))) | |
:else | |
(cond | |
(= (first form) '<>) | |
(let [g (gensym "d__")] | |
(recur [(conj a g) (concat f (list g))] (next form))) | |
(= (first form) '<...>) | |
(let [g (gensym "vd__")] | |
(recur [(reduce conj a ['& g]) (concat '(apply) f (list g))] (next form))) | |
:else | |
(recur [a (concat f (list (first form)))] (next form))))) | |
(defmacro cut | |
"The amazing cut macro." | |
[& forms] | |
(let [[arg-list xform] (cut* [[] '()] forms)] | |
`(fn ~arg-list | |
~xform))) | |
(comment | |
(map (cut assoc <> :foo 42) [{:a 1} {:b 2} {:c 3}]) | |
;=> ({:foo 42, :a 1} {:foo 42, :b 2} {:foo 42, :c 3}) | |
(map (cut <> <>) (repeat 2 [inc dec]) (repeat 42)) | |
;=> (43 41 42 41) | |
;;; <...> is used for var args | |
(cut + 1 2 <...>) | |
;=> (fn [& args] (apply + 1 2 args)) ; macro-expansion | |
((cut + 1 2 <...>) 3 4 5 6) | |
;=> 21 | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment