On Sat, Jun 19, 2010 at 5:41 AM, Heinz N. Gies <he...@licenser.net> wrote:
> Lets get away from the argument already cast and bring a new one. It is an > impossible situation that the literal 1 in one place has a different meaning > and behavior then in another place. This is in fact a show stopper, I'm > serious, this would be worst then java. > > (* 1 0.2) -> works fine > > but > > (loop [n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2)))) > > does not because the 1 there is not the 1 in the upper example, that is so > utterly wrong and horrible please think about it and think about how you'd > sell someone he has to know where a literal means what, I can guarantee you > this will keep many people from this wonderful language :(. I think you're misinterpreting what's going on here. There's no trickery with the type of 1 or r, and the expression (* r 0.2) will correctly return 0.2. The problem is that when 0.2 is passed into recur, it's coerced to a long, so it becomes 0. I do agree that the end result is unfortunate. I would be much happier if types of loop variables were based not just on their initializers, but also on the types of the arguments to recur. This would certainly result in some needless boxing, but the compiler would still be able to use primitives in a lot of cases. In particular, it could use primitives whenever the loop variable's new value is computed using only arithmetic operators or other :static functions that return primitives. The only possible harm would come from a very particular set of circumstances: (1) the loop variable is initialized with a primitive, (2) the performance of the loop depends in the variable being primitive, (3) a the compiler can't prove that the variable is re-bound with a primitive in a recur form, and (4) the actual value used to re-bind the variable is a boxed primitive of same type as the variable's initializer. If (1) is not true, the variable would not be primitive anyway; if (2) is not true, there may be some unnecessary boxing, but it doesn't hurt anything; if (3) is not true, the compiler can use primitives just as it does now; and if (4) is not true, the compiler is correctly forced to use a boxed type for the variable, whereas today it incorrectly tries to unbox the value, resulting in either a ClassCastException or a numeric conversion that silently loses precision. -- 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