> but I don't see how it applies to the case float / int
Does the int get converted to a float for this calculation? is sizeof(int) == sizeof(float)? Then you can lose accuracy in the conversion; MAX_INT is larger than the largest same-sized float that can be represented without rounding error.
Fair point, although for the garden-variety int (int32) and float64, this isn't the case. In an ideal world, the compiler would be smart enough to know this, and complain appropriately.
So, you're saying that you want a table that looks like this:
Type 1 | Type 2 | Allowed?
--------------------------
float32 | int32 | n
float32 | int64 | n
float64 | int32 | y
float64 | int64 | n
etc...
Seems a bit odd to have the majority of conversions banned, but allow some random-seeming exceptions that are safe.
Since implicit conversions are almost always either lossy or dangerous (think 'Fahrenheit(32) - Celsius(64)'), I think it makes sense to remove implicit promotions entirely.
It doesn't seem odd to me. In fact I think it might be a Good Thing.
Having the compiler take care of the safe cases for one makes one less likely to always blindly cast things and leave oneself open to the unsafe cases. For certain values of 'one', of course :)
As for your point about Fahrenheit, the real solution is
type DegreesF float64;
type DegreesC float64;
so that the units cannot be accidentally mixed.
Note to self: It might not be a bad idea to have alias-style types deliberately not participate in automatic numeric conversions, although I think it is a mistake they don't currently always auto-convert to their own aliased type.
Or just write your code so you don't need to convert types. I think that's entirely doable, with the possible exception of API boundaries, and removes the need to have complicated and confusing rules about allowed conversions.
And yes, as far as different unit types, you just pointed out exactly what I was getting at. It's relatively rare that you want implicit type conversions.
Maybe so, maybe so. I do agree that numeric implicit conversion is not as simple as it first seemed to me, and would have knock-on effects elsewhere.
Edit: For the record, here are the rules we've discovered so far:
1. Numeric casts: A -> B happens automatically if every value of A can be represented exactly in B. Both must be base types.
2. Aliased casts: A -> B happens automatically if A is an alias of B.
3. Automatic casts only happen if a single automatic cast is required, not more. In other words, x + y should not cause x and y to both be cast to a common type.
Indeed, in fact that's why rune has been added to the language little more than 6 months ago. Now that rune is used instead of int for representing unicode code points, int can be extended to 64 bit.
That's true, and it will probably change fairly soon, but there are a whole range of safe integer to float casts that will still exist even if int changes from int32 to int64.
And these safe casts should be transparent so that people who regularly do things with floats don't feel like second class citizens in the language.
The check cannot be made at compile time, only at run time, and even if it were possible to make the check at compile time it would still be a bad idea. At some point in the program's 20 year old life time, someone will decide that a number N used somewhere in the program has to become N+1, and N+1 doesn't work. It would be unacceptable for such a trivial change to break the program's compilation, and for a number to carry so much hidden state and meaning.
I don't understand why people are so afraid of compile time errors. They're great! They help us write code and reason about it.
If someone changes some ossified piece of code, and that has the effect that it makes an automatic cast semantically dangerous, I'd be extremely grateful if the compiler scolded me with a helpful error message.
I'm not sure what you mean by "The check cannot be made at compile time, only at run time". Are you talking about a language other than Go? Go is statically typed.
edit: I've been talking about compile time errors that prevent potentially dangerous implicit casts from happening. I think you're talking about something else.
If int64 is the default type for int, then any int will be able to contain values not representable as a float64 (you'd need a float80 or float128 to make it work). To safely convert, a run-time check will be needed.
Does the int get converted to a float for this calculation? is sizeof(int) == sizeof(float)? Then you can lose accuracy in the conversion; MAX_INT is larger than the largest same-sized float that can be represented without rounding error.