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

Reply via email to