I get why float32 can auto convert to float64... there is no loss in precision.
But its strange to me that reverse is also true. Nim will auto convert a float64 to a float32 and loose precision!!! Silently! This is not true for ints.
Here it states so in the manual: https://nim-lang.org/docs/manual.html#type-relations-convertible-relation
var
a: float64 = 20e-70
b: float32 = a
c: float64 = b
echo a
echo b
echo c
Output:
2e-69
0.0
0.0
You can see here we had float64 of 20e-70 go through an intermediate float32 that rounded it, so that the next float64 was 0.
My fear that its easy to have a random float32 in your code that is basically a rounding function. And you will never know!
Thoughts? Why was it done like this? Do you guys think this is good? Does it matter? Can't change now because too much code depends on it?
I don't see where the silently is, you are forcing a type conversion. In JS nearly the whole language can be converted back and forth.
I would see that dangerous if you don't declare the type of "b" and the compiler implies float32, but if you declare its type, that's not silently for me.
For me it is silently.
Mixing float64 and float32 unintentionally can be dangerous for precision and have disadvantage for performance.
May we allow that mixing only when lenientOps is imported or can compiler give us warnings at least?
I'm not sure if this is related behavior, but @treeform made this post after trying to figure out the following code:
type Elem = float32 or float64
type Vec2[T : Elem] = object
x : T
y : T
proc vec2[T:Elem](x, y: T) : Vec2[T] = Vec2[T](x: x, y: y)
let a = vec2(1f32,2f64)
let b = vec2(1f64,2f32)
echo typeof(a) # Vec2[system.float32]
echo typeof(b) # Vec2[system.float64]
The OP's code wasn't very surprising to me, as it was explicitly casting, but this one here is very surprising to me.
I don't see where the silently is
It's silent because there's no warning of the loss of precision.
you are forcing a type conversion
By this reasoning, there are no silent type conversions, just type conversions, all of which are "forced" by the semantics of the language.
In JS nearly the whole language can be converted back and forth.
And your point is ...? JS is not a good model.
if you don't declare the type of "b" and the compiler implies float32
type
a: float64 = 20e-70
b = a # b is float32
wouldn't be a silent type conversion, it would just be absurd.