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