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 <al...@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-...@swift.org <mailto:swift-build-...@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-...@swift.org <mailto:swift-build-...@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-build-dev 
>> <https://lists.swift.org/mailman/listinfo/swift-build-dev>
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to