Auto-convert for numbers when safe


(William Shipley) #1

I’m new to this discussion and don’t really know what’s been tried before, so I’m probably asking stupid questions, but I *really* want auto-conversion…

What would be the drawback in terms of language design to just allowing types to specify what other types can automatically be “upconverted" to them? True, this could be used to create a cyclic graph, but that could just be disallowed in the compiler—you guys like writing code, right?

I think one of the issues with all this is that Swift allows us to skip specifying types, like:

   let a = 1

   let b: CGFloat = a + 3

And so it’d be easy to get into a morass where the poor compiler is all, “AH! I should go back in time and make ‘a’ a CGFloat automatically, not an Int like I want, so it’ll add with 3 and make a nice CGFloat!”

Is that the problem we’re fighting? If not, what was the issue with the (unreleased) auto-conversion code that was in Swift.

-Wil


(Brent Royal-Gordon) #2

I’m new to this discussion and don’t really know what’s been tried before, so I’m probably asking stupid questions, but I *really* want auto-conversion…

What would be the drawback in terms of language design to just allowing types to specify what other types can automatically be “upconverted" to them? True, this could be used to create a cyclic graph, but that could just be disallowed in the compiler—you guys like writing code, right?

Chris Lattner discussed this yesterday. I can’t find it in the online archives, so I’ll copy-and-paste it here:

···

From: Chris Lattner via swift-evolution <swift-evolution@swift.org>
Date: December 5, 2015 at 11:02:47 PM PST
To: Jonathan Hull <jhull@gbis.com>
Cc: swift-evolution@swift.org
Subject: Re: [swift-evolution] Proposal: Auto-convert for numbers when safe

On Dec 5, 2015, at 4:27 AM, Jonathan Hull <jhull@gbis.com> wrote:

I understand why you can’t auto-convert from a Double to a Float or Int32 to Int8. It is good that we have to add the cast explicitly and think though the implications.

…but I don’t think through the implications because we currently have a boy who cried wolf situation where we have to explicitly cast everything (even the safe stuff).

I think all of the numeric types should be able to auto-convert if the conversion is safe (without loss of precision or overflow).

For example:
• If an Int is casting to a larger size (Int16 -> Int32)
• Float -> Double
• Float -> CGFloat
• Int -> Float, Double, or CGFloat (but not the other way)

I don’t see why these aren’t allowed. The forced casts make my code much less readable. Are the casts above dangerous in a way I am not aware of?

I agree that the current Swift numerics model is suboptimal, I personally would like to see small integers implicitly promote to large integers (when they are known lossless), have Float promote to Double, and have both Float and Double promote to CGFloat (yes, I know that the Double -> CGFloat promotion would be lossy on 32-bit apple platforms). I personally don’t think that integer -> floating point promotions are a good idea even if value preserving, since their domains are so different.

The problem with doing this today is that there are a lot of dependencies we need to get resolved first.

1. The type checker is really slow, partially because of too-many and too-crazy implicit conversions. We also get very surprising behavior when they kick in. Specifically, IMO, we need to reevaluate the T! <-> T and T to T? conversions. We have thoughts on this, but should be discussed in a separate thread if you’re interested.

2. These promotions should be expressible in the library, not hard coded into the compiler. This means that we would need a language feature to (e.g.) be able to define subtype relationships between structs. Such a feature would be generally useful and could allow us to push some of our existing compiler magic out to the stdlib.

3. We want the existing work to revise the numerics protocols to be better understood and hopefully implemented.

There are also a ton of unrelated specific problems that should be addressed in various ways: e.g. macros like M_PI get imported as Double instead of a typeless literal, forcing tons of casts in code that wants to use it (e.g.) with Floats. These issues are separable, and blocked on things like generic properties not being in place.

It would be great for interested contributors to start pushing on any of the above issues to help unblock progress on improving the numerics model.

-Chris

--
Brent Royal-Gordon
Architechies


(William Shipley) #3

Chris Lattner discussed this yesterday. I can’t find it in the online archives, so I’ll copy-and-paste it here:

Right, I read Chris’s message and was trying to respond to it. I guess what I’m saying is I’m not clear what’s missing: do we not know what syntax we’d use, or do we just not know how to implement that syntax, or do we just not even know all the implications of adding this?

-WIl


(Chris Lattner) #4

The “first step” in making progress on this is to fix the existing constraint solver problems (and the emergent surprising user behavior) handling of optionals and IUOs. Until that gets resolved, it doesn’t make sense to dig a deeper hole :-)

-Chris

···

On Dec 7, 2015, at 1:26 AM, William Shipley via swift-evolution <swift-evolution@swift.org> wrote:

Chris Lattner discussed this yesterday. I can’t find it in the online archives, so I’ll copy-and-paste it here:

Right, I read Chris’s message and was trying to respond to it. I guess what I’m saying is I’m not clear what’s missing: do we not know what syntax we’d use, or do we just not know how to implement that syntax, or do we just not even know all the implications of adding this?