Fork me on GitHub

ahhh I love the lisps

Geoffrey Gaillard16:10:19

Anyone here knows how I could invoke a static method on a class from one of its instance? I have a (defrecord Foo [bar baz]) and I want to access Foo/create but the only reference I have is an instance of Foo. I tried (.create (class foo-instance) {}) but this searches amongst instance methods. Any ideas?


you need to use reflection


user=> (defrecord Foo [bar])
user=> (let [inst (Foo. 1)] (clojure.lang.Reflector/invokeStaticMethod (.getName (class inst)) "create" (object-array [{:bar (.-bar inst)}])))
#user.Foo{:bar 1}

Geoffrey Gaillard17:10:10

Didn't knew about c.l.Reflector/invokeStaticMethod! I'm going to try that. Thank you!

Geoffrey Gaillard17:10:08

It did the trick :thumbsup:


While it is easy to come up with an example where type-hinting a function argument with ^long has a performance advantage, I cannot find an example where hinting the return of the function makes any difference. Can anyone suggest one?


I thought maybe (defn foo ^long [] 5) would make a difference in (time (dotimes [x 10000000] (+ (foo) (foo)))) But apparently not


this is a good example, and a terrible benchmarking methodology :)


if you used criterium instead of time+`dotimes` you would've noticed that it is indeed faster than using (defn bar [] 5)


well, that benchmarking using time works well enough in the hinted parameter example (and is on the site for its examples of type hinting performance gains)


[~]> clj -A:bench
Clojure 1.10.0-master-SNAPSHOT
user=> (use 'criterium.core)
user=>  (defn bar [] 5)
user=>  (defn foo ^long [] 5)
user=> (quick-bench (+ (foo) (foo)))
Evaluation count : 135075996 in 6 samples of 22512666 calls.
             Execution time mean : 2.208218 ns
    Execution time std-deviation : 0.422297 ns
   Execution time lower quantile : 1.935788 ns ( 2.5%)
   Execution time upper quantile : 2.928008 ns (97.5%)
                   Overhead used : 2.390831 ns

Found 1 outliers in 6 samples (16.6667 %)
	low-severe	 1 (16.6667 %)
 Variance from outliers : 48.2198 % Variance is moderately inflated by outliers
user=> (quick-bench (+ (bar) (bar)))
Evaluation count : 35692152 in 6 samples of 5948692 calls.
             Execution time mean : 15.873007 ns
    Execution time std-deviation : 1.651083 ns
   Execution time lower quantile : 14.405037 ns ( 2.5%)
   Execution time upper quantile : 17.695135 ns (97.5%)
                   Overhead used : 2.390831 ns


then the clojure website has a terrible benchmark too :)


going to try criterium now, thanks


On a related note, I had floating in my head that a turbocharged defn-spec could try inferring/emitting ^long annotations out of user-suplied specs Has anyone tried so?