From d7de884dc75ac9b017234a9a633f642bef9fbb04 Mon Sep 17 00:00:00 2001 From: Brandon Bloom Date: Wed, 21 Nov 2012 13:25:45 -0800 Subject: [PATCH 1/2] Fix IFn this-sym --- src/clj/cljs/core.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clj/cljs/core.clj b/src/clj/cljs/core.clj index 361a0bf..e62f966 100644 --- a/src/clj/cljs/core.clj +++ b/src/clj/cljs/core.clj @@ -490,13 +490,13 @@ (mapcat (fn [[f & meths :as form]] (if (= psym 'cljs.core/IFn) (let [adapt-params (fn [[[targ & args :as sig] & body]] - (let [this-sym (with-meta (gensym "this-sym") {:tag t})] + (let [this-sym (with-meta 'self__ {:tag t})] `(~(vec (cons this-sym args)) (this-as ~this-sym (let [~targ ~this-sym] ~@body))))) meths (map adapt-params meths) - this-sym (with-meta (gensym "this-sym") {:tag t}) + this-sym (with-meta 'self__ {:tag t}) argsym (gensym "args")] [`(set! ~(prototype-prefix 'call) ~(with-meta `(fn ~@meths) (meta form))) `(set! ~(prototype-prefix 'apply) -- 1.8.0 From 104868ed3e219d81bf989ac9241350d55420ab0a Mon Sep 17 00:00:00 2001 From: Brandon Bloom Date: Wed, 21 Nov 2012 13:26:53 -0800 Subject: [PATCH 2/2] CLJS-359: Support metadata on functions. --- src/cljs/cljs/core.cljs | 21 ++++++++++++++++++++- test/cljs/cljs/core_test.cljs | 10 ++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/cljs/cljs/core.cljs b/src/cljs/cljs/core.cljs index a227b84..f81455a 100644 --- a/src/cljs/cljs/core.cljs +++ b/src/cljs/cljs/core.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))) diff --git a/test/cljs/cljs/core_test.cljs b/test/cljs/cljs/core_test.cljs index 35d906c..bf425d0 100644 --- a/test/cljs/cljs/core_test.cljs +++ b/test/cljs/cljs/core_test.cljs @@ -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))) -- 1.8.0