[swift-evolution] Proposal: Auto-convert for numbers when safe

Manav Gabhawala manav1907 at gmail.com
Sat Dec 12 02:03:23 CST 2015

 Thanks for your feedback Doug.

With regards to your first concern, I think that we won't actually lose any
symmetry because if the user actually wants backward conversions they will
define it themselves and so we won't ever have the case where we are giving
this behavior for "free" and so the compiler will only have to do a one
level check of an implicit conversion. And while we want to support the
castingFrom implicit initializer (which can be failable if need be) it will
always be user defined and never generated by a protocol extension or the
compiler so things will still be Swifty.

>From a technical standpoint I can't say much because I have no compiler
experience whatsoever (yet). But I can see how this might mess around with
the type checker and I can understand why this might be too difficult to
implement for swift 3. However, I strongly believe the current numbers
model of explicit conversion is too verbose and very non swift like. One of
the biggest problems is the way that Int types are imported from C
libraries and you have to keep converting back and forth between for
example a UInt32 and an Int or something similar. Would you be open to
restricting the feature to only work with number types and "hard code" that
behavior into the compiler for swift 3 or do you think that's something we
should not proceed with, or have a different solution for solving the
numbers problem?

Manav Gabhawala

On December 12, 2015 at 1:57:10 AM, douglas gregor (dgregor at apple.com)

> On Dec 6, 2015, at 11:48 PM, Manav Gabhawala via swift-evolution <
> swift-evolution at swift.org> wrote:
> I created a pull request with the proposal: Implicit Initializer proposal
> <https://github.com/apple/swift-evolution/pull/37> (
> https://github.com/apple/swift-evolution/pull/37). Feel free to respond
> with suggestions/ideas with improvements to the proposal and things that
> may be missing.
> I have two comments. The first is on the suitability of this proposal for
> Swift as a language; the second is about technical feasibility of the
> proposal.
> Regarding suitability for Swift: for the most part, Swift’s type system
> has a set of subtyping relationships that allow implicit conversions
> (during compilation) that can be safely reversed via conditional
> downcasting (the “as?” operator). For example, say I have:
> protocol P { }
> struct X : P { }
> I can turn an X into a P:
> var p: P = X()
> and then reverse the operation with a cast:
> if let x = p as? X { … }
> It’s a rather beautiful and powerful symmetry to the language. If we add
> implicit conversions:
> struct X {
>   implicit init(_ y: Y) { … }
> }
> struct Y { }
> var x: X = Y()
> Should we allow
> let y = x as? Y { … }
> to work? If no, we’ve lost some useful symmetry to the type system.
> If yes, we first need to figure out how the user can implement it… perhaps
> some opposite operation that can fail:
> extension Y {
>   init?(castingFrom: X) { … }
> }
> but how can we implement this in an efficient manner in the runtime? We
> would effectively have to represent the DAG of implicit conversion
> relationships in runtime data structures and evaluate those with every
> “as?” cast, which implies a heavy runtime burden for using this feature.
> On technical feasibility: introducing user-defined conversions is a major
> complication to the type system, particularly in a language with general
> type inference. We did go down this route (there are vestiges of it still
> remaining in the expression type checker), and it added a huge amount of
> complexity to the type checker that compromised it’s ability to provide
> good type inference. We would need a massive improvement to the expression
> type checker for this to become technically feasible, and I’m not sure we
> even can get there. Swift has a complicated type system already—general
> type inference, parametric polymorphism, ad hoc overloading, general
> subtyping—and the type checker is one of the weaker areas of the
> implementation in part because of that complexity.
> I don’t think we can bring a proposal up for review when there is a
> significant chance that it cannot be faithfully implemented. Obviously,
> asking you to “go implement a revolutionary new type checker” isn’t a great
> response, either, which leaves us in the unfortunate position of looking
> for some kind of assurance that, should we decide we want to go in this
> direction, we actually *can* go in this direction.
> - Doug
> Regards,
> Manav Gabhawala
> On December 6, 2015 at 5:33:37 PM, Matthew Johnson via swift-evolution (
> swift-evolution at swift.org) wrote:
> I would be happy with any solution that provides failable conversion so I
> would support that as well.
> Any chance we could see something like this in Swift 2.2 or Swift 3? I was
> hoping the failable initializers might be low hanging fruit but it seems
> like the scoped feature would be more than that.
> Sent from my iPad
> > On Dec 6, 2015, at 4:04 PM, Chris Lattner <clattner at apple.com> wrote:
> >
> > Could definitely be interesting. I’d personally like to turn it into a
> scoped feature along the lines of this post though:
> >
> >
> https://lists.swift.org/pipermail/swift-evolution/2015-December/000292.html
> >
> > -Chris
> >
> >> On Dec 6, 2015, at 5:29 AM, Matthew Johnson <matthew at anandabits.com>
> wrote:
> >>
> >> Related to this, but maybe easier to do in the short term: what do you
> think of adding failable overloads to the numeric conversion initializers
> Chris?
> >>
> >> They would throw or return nil if the runtime value could not be
> preserved rather than trap, truncate, etc. Floating point types might allow
> a tolerance for small value changes due to precision, although I'm not sure
> if that would be good or not. These initializers would be very useful when
> processing data from an external source such as JSON that has an expected
> type but cannot be trusted.
> >>
> >>
> >>
> >> Sent from my iPad
> >>
> >>>> On Dec 6, 2015, at 1:02 AM, Chris Lattner via swift-evolution <
> swift-evolution at swift.org> wrote:
> >>>>
> >>>> On Dec 5, 2015, at 4:27 AM, Jonathan Hull <jhull at 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
> >>>
> >>> _______________________________________________
> >>> swift-evolution mailing list
> >>> swift-evolution at swift.org
> >>> https://lists.swift.org/mailman/listinfo/swift-evolution
> >
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>  _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151212/1d0baab2/attachment.html>

More information about the swift-evolution mailing list