Fork me on GitHub
#clojure
<
2018-10-14
>
Cameron06:10:15

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?

bronsa16:10:37

you need to use reflection

bronsa16:10:24

user=> (defrecord Foo [bar])
user.Foo
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:

ajs17:10:47

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?

ajs17:10:09

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

bronsa17:10:39

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

bronsa17:10:06

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

ajs17:10:26

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

bronsa17:10:31

[~]> clj -A:bench
Clojure 1.10.0-master-SNAPSHOT
user=> (use 'criterium.core)
nil
user=>  (defn bar [] 5)
#'user/bar
user=>  (defn foo ^long [] 5)
#'user/foo
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
nil
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
nil

bronsa17:10:55

then the clojure website has a terrible benchmark too :)

ajs17:10:48

going to try criterium now, thanks

vemv23:10:40

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?