> >> (a) unsafe/incorrect value on overflow/fastest/unifiable* vs. > >> (b) safe/error on overflow/fast/unifiable vs. > >> (c) safe/promoting on overflow/slow/not-unifiable > > > If I understand correctly, the issue with auto-promotion is that we > > have to box the output of an operation even if it turns out to fit in > > a long, since the compiler must specify whether the result will be > > long or Object. > > > This is probably a stupid question, but since Clojure is already > > testing for overflow in (b) to throw an exception, would it be > > possible to jump into an alternative (c)-type compilation of the > > function just-in-time to promote on overflow instead? It seems like > > this could achieve the performance of (b) while still allowing for > > auto-promotion (albeit perhaps with a performance hit in that case, > > code bloat, compromises about how many versions to compile, etc.). > > When Clojure compiles your function, it emits JVM bytecode for a new > class which is then loaded by the classloader. That JVM bytecode > defines a function (well, a method as far as the JVM is concerned) > which returns either a primitive type or Object. Your suggestion > would involve redifining the class while it is executing. That's not > possible on the JVM. Even if it were possible -- your function now > returns Object instead of long.
If I understand correctly, the return type of your function is not up for interpretation. It is Object if undeclared, and primitive only if declared -- so that is not a problem (if you ask for long, that's what you'll get). I am only talking about behavior within a single function call -- no calling code needs to change. Moreover, we do not need to redefine the class at run-time. A simple way to do this: when you compile a function with arithmetic operations, concatenate bytecode for two versions: essentially, one with the unprimed (exception-throwing) ops and one with the primed (overflowing) ones. Now, replace the exceptions in the first path with local jumps into the second path. There are probably ways to get around generating two copies of the bytecode in advance, and making such a unilateral shift to inefficient semantics, but I don't know enough about JVM internals to say for sure. -- 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