Permalink
Browse files

CLJS-359: Support metadata on functions.

  • Loading branch information...
1 parent ebe40c8 commit 6ce3b1cef3824fd36e75402f5a8ed5053252b15e @brandonbloom brandonbloom committed with David Nolen Nov 21, 2012
Showing with 30 additions and 1 deletion.
  1. +20 −1 src/cljs/cljs/core.cljs
  2. +10 −0 test/cljs/cljs/core_test.cljs
@@ -128,6 +128,9 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;; core protocols ;;;;;;;;;;;;;
+(defprotocol Fn
+ "Marker protocol")
+
(defprotocol IFn
(-invoke
[this]
@@ -456,6 +459,22 @@
(-hash [o]
(if (identical? o true) 1 0)))
+(extend-type function
+ Fn
+
+ IMeta
+ (-meta [_] nil)
+
+ IWithMeta
+ (-with-meta [f meta]
+ (with-meta
+ (reify
+ Fn
+ IFn
+ (-invoke [_ & args]
+ (apply f args)))
+ meta)))
+
(extend-type default
IHash
(-hash [o]
@@ -1026,7 +1045,7 @@ reduces them without incurring seq initialization"
(goog/isNumber n))
(defn ^boolean fn? [f]
- (goog/isFunction f))
+ (or ^boolean (goog/isFunction f) (satisfies? Fn f)))
(defn ^boolean ifn? [f]
(or (fn? f) (satisfies? IFn f)))
@@ -400,6 +400,16 @@
(assert (nil? (f :foo))))
(assert (nil? (array-seq (array 1) 1)))
+ ;; Functions with metadata
+ (let [f (fn [x] (* x 2))
+ m {:foo "bar"}
+ mf (with-meta f m)]
+ (assert (nil? (meta f)))
+ (assert (fn? mf))
+ (assert (= 4 (mf 2)))
+ (assert (= 4 (apply mf [2])))
+ (assert (= (meta mf) m)))
+
(let [a (atom 0)]
(assert (= 0 (deref a)))
(assert (= 1 (swap! a inc)))

0 comments on commit 6ce3b1c

Please sign in to comment.