[swift-build-dev] "Swift 4.1 or Swift 3.3"
Jordan Rose
jordan_rose at apple.com
Mon Jan 8 15:37:02 CST 2018
Thanks for the info, Alan!
On `swift(<4.0)`: I think originally we were even more restrictive about how people used `#if swift`, not even allowing !, &&, and ||. Without those restrictions, allowing a `swift(<x.y)` seems reasonable. However, I don't think that really makes the compound condition significantly nicer. (> and <= are very deliberately not included, because people always forget point releases.)
Jordan
> On Jan 5, 2018, at 17:22, Alan Zeino <alanz at uber.com> wrote:
>
> Hey Jordan,
>
> We tend to have to do major migrations of our Swift codebase, so I might be able to help. For context at last count (February 2017 was the last time I checked) we had 1.4m lines of Swift across our apps.
>
> This means that when we migrate, we tend to have to chose the smallest possible scope for necessity reasons. For example when Swift 3.0 was available, we went to 2.3 first and it took a few months before we were on 3.0.
>
> When 4.0 was available we went to 3.2 first (with many, many #if statements) and it took a few months before we went to 4.0; which we did by landing many months worth of #if statements to switch between 3.2/4.0 right up until the 4.0 switch.
>
> To answer the last question first, the larger the codebase the more likely you will be to want to do your swift migrations piecemeal with many small changes until you can build a fully–compatible–with–the–new–version executable.
>
> This is even more important for open source libraries, who struggle with either having entire forked branches for swift versions (which means fixes sometimes have to be committed to more than one branch), or many #if statements littered in their codebase.
>
> As for this issue, the main improvement here would be to be able to use > and < in these statements. The first time I had to do one of these large migrations I found it more difficult to reason and read the cases where you had to do this:
>
> #if !swift(>=3.2)
> /* code */
> #endif
>
> …when it would be a little easier to grok what’s happening if it were possible to do this:
>
> #if swift(<3.2)
> /* code */
> #endif
>
> In your example, it could be a little simpler if the unary requirement here was relaxed (though I’m sure there’s a good reason why it’s the way it is!).
>
> If I’m reading this correctly (sorry if my interval notation is wrong it’s been a while) the bounds here would be:
>
> // n >= 4.1
> // or
> // 3.3 >= n < 4.0
> #if swift(>=4.1) || (swift(>=3.3) && !swift(>=4.0))
> print("asdf")
> #endif
>
> But if it were possible to use > and <, it would read:
>
> #if (swift(>=3.3) && swift(<4.0)) || swift(>=4.1)
> print("asdf")
> #endif
>
> (I don’t know why Mail.app is making the < above look like a less than or equal to symbol ≤)
>
> I find it a little easier to read it this way, because the negation with ! changes my thinking from ‘interval’ to ‘interval plus… not something in this interval’.
>
> Overall, while I think that most people here know that these compatibility versions are really ‘the old code built with the latest compiler’, most tend to ignore this fact so we try not to worry about it much and trust the compiler a lot here to do the right thing. We also try to only support one Xcode version at Uber at a time (and so one swift compiler toolchain), which tends to narrow the scope of the ‘what version of Swift will this code compile for’ question.
>
> Hope this helps!
>
> Alan
>
>
>> On Jan 5, 2018, at 4:19 PM, Jordan Rose via swift-build-dev <swift-build-dev at swift.org <mailto:swift-build-dev at swift.org>> wrote:
>>
>> Hi, all. Swift 4.1 is off on its own branch and going well, but we never quite came up with an answer for a particular problem developers might have: "am I running a Swift 4.1 compiler?".
>>
>> #if swift(>=3.2)
>> // Swift 3.2 (4.0 in compatibility mode)
>> // Swift 3.3 (4.1 in compatibility mode)
>> // Swift 4.0
>> // Swift 4.1
>> #endif
>>
>> #if swift(>=3.3)
>> // Swift 3.3 (4.1 compatibily mode)
>> // Swift 4.0
>> // Swift 4.1
>> // this one is probably not very useful
>> #endif
>>
>> #if swift(>=4.0)
>> // Swift 4.0
>> // Swift 4.1
>> #endif
>>
>> #if ???
>> // Swift 3.3
>> // Swift 4.1
>> #endif
>>
>> I don't think this is going to come up a lot, but given that we do have changes to the standard library and to the language, I can see people wanting it. Right now the only way to do it is the rather unwieldy:
>>
>> #if swift(>=4.1) || (swift(>=3.3) && !swift(>=4.0))
>> print("new")
>> #else
>> print("old")
>> #endif
>>
>> Do we need something better here, or do you think people will be okay with this? I'm realizing I don't really know how many people try to keep their libraries working across Swift versions and run into compatibility issues.
>>
>> (Strictly speaking this problem is already present with Swift 4.0.2 with 3.2.2 compatibility mode, but that's much less likely to come up.)
>>
>> Jordan
>> _______________________________________________
>> swift-build-dev mailing list
>> swift-build-dev at swift.org <mailto:swift-build-dev at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-build-dev <https://lists.swift.org/mailman/listinfo/swift-build-dev>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-build-dev/attachments/20180108/69c64aa6/attachment.html>
More information about the swift-build-dev
mailing list