I agree with the general sentiment: add typehints later, and only if you need performance in this particular part of the code. I object to the characterization as a "small loss of performance", though. A reflective method call takes about five hundred times as long as a hinted method call in the following benchmark, so if you do have a performance-sensitive section of your program that needs to do a lot of interop, the improvement is dramatic, not small.
user> (time (dotimes [_ 1e6] (let [s (identity "test")] (.length s)))) "Elapsed time: 15490.471302 msecs" user> (time (dotimes [_ 1e6] (let [s (identity "test")] (.length ^String s)))) "Elapsed time: 34.561754 msecs" On Oct 19, 10:35 pm, Luc Prefontaine <lprefonta...@softaddicts.ca> wrote: > Just use ^ for type hints. > > http://clojure.org/java_interop#Java%20Interop-Type%20Hints > > Type hints are used to eliminate reflection calls, the compiler can use the > exact type > of the parameter to eliminate the runtime cost of finding if methods/fields > exist > before calling/accessing them. > > user=> (set! *warn-on-reflection* true) > true ;;; <== tells the compiler to complain about reflection calls > user=> (defn a [b] (.startsWith b "a")) > Reflection warning, NO_SOURCE_PATH:23 - call to startsWith can't be resolved. > <=== Oups ! > #'user/a > user=> (a 1) > java.lang.IllegalArgumentException: No matching method found: startsWith for > class java.lang.Integer (NO_SOURCE_FILE:0) > > This definition has no type hint, the compiler flags a warning to say that it > cannot resolve the method startsWith. > If you try to call the first form with an object not implementing startsWith, > the runtime traps that it did not find the method on that > object's class. The flexibility comes with a cost, finding the method on the > fly. > > user=> (defn a [^String b] (.startsWith b "a")) > #'user/a > user=> (a 1) > java.lang.ClassCastException: java.lang.Integer cannot be cast to > java.lang.String (NO_SOURCE_FILE:0) > > Here the compilation does not trigger the reflection warning, the argument > type has been hinted as a string. > The compiler can find the method immediately and generate the code without > any runtime "search". > > At runtime, if you ever call the second form with a non string object, this > time you get that the argument type > is not the one expected (from the type hint). The compiler has added a type > check instead > of relying on the dynamic search for methods/fields in the class which is > faster. > > Note that it's not data typing per se. You are allowed to call the form with > a different object class. > The compiler will not scream, the runtime will if you persists to call the > method. > > Form #1 allows you to pass objects of any class that implements startsWith > with a small loss of performance. > In form #2 you can gain performance at the expense of generality. > > Type hints are to be to improve performance AFTER your code is more or less > stable. > If you use type hints early in your development, you will carry them all the > way and that can be a > significant pain. > > Luc P. > > On Wed, 19 Oct 2011 22:03:31 -0700 (PDT) > > > > > > > > > > mmwaikar <mmwai...@gmail.com> wrote: > > Hi, > > > I read in "Clojure in Action" book by Amit Rathore, that #^ > > associates metadata for the next form. He also mentions that it is > > deprecated. So what is the current way of doing it? > > > Also, in code like this - > > > (defn filenames-in-jar > > "Returns a sequence of Strings naming the non-directory entries in > > the JAR file." > > [#^JarFile jar-file] > > > is it specifying that the type of the jar-file argument should be > > JarFile? > > > Where can I find some more documentation and or examples about it? > > > Thanks, > > Manoj. > > -- > Luc P. > > ================ > The rabid Muppet -- 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