Some time ago I dug into primitive type hints and how the Clojure compiler uses them. When the compiler finds primitive type hints on a function, say (defn f [^long n] ...), the generated class for that function implements a primitive interface, IFn$LO in this case, and generates appropriate code in the interface's only method Object invokePrim(long arg0).
For a defn which is used as symbol in code the compiler detects the primitive interface and generates code using invokePrim if the infered type of the parameters matches. Long story short, currently the compiler is not able to use primitive invocation for higher order functions automatically because it would need to generate code that checks at runtime. You can fix this with Java interop. I implemented an `invoke-primitive` macro over here: https://gist.github.com/guv/5458038 It could be used like follows: (defn calc [^long n] ...) (defn dosomething [f, ^long n] (invoke-primitive O [L] f n)) The macro expands to (.invokePrim ^IFn$LO f n) using several checks at compile time. Am Mittwoch, 24. April 2013 19:15:49 UTC+2 schrieb Alice: > > So, is there a way to type hint on cb that it has a function accepting > a long argument? > > On Apr 25, 12:55 am, Stuart Sierra <the.stuart.sie...@gmail.com> > wrote: > > I'm taking a guess here: The compiler doesn't know the type signature of > > `cb` when compiling `foo`, so it's going to use the IFn.invoke(Object) > > signature. Clojure's type inference is only local, and it won't assume > that > > a primitive-type signature is available for an arbitrary function. > > > > So there's probably some extra typecasting going on when `fn` is > > type-hinted to a primitive. > > > > In general, type-hinting to primitive types doesn't do you any good in > the > > presence of higher-order functions like `map`. > > > > -S > > > > > > > > > > > > > > > > On Wednesday, April 24, 2013 11:35:11 AM UTC-4, Alice wrote: > > > > > (defn foo [^long l cb] (cb l)) > > > > > (time > > > (dotimes [n 1000000] > > > (foo n (fn [l] nil)))) > > > > > (time > > > (dotimes [n 1000000] > > > (foo n (fn [^long l] nil)))) > > > > > "Elapsed time: 7.861 msecs" > > > "Elapsed time: 11.770973 msecs" > > > > > Why is the latter slower? > -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.