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.


Reply via email to