<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hey Jordan,<div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.&nbsp;</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">As for this issue, the main improvement here would be to be able to use <font face="Menlo" class="">&gt;</font> and <font face="Menlo" class="">&lt;</font> 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:</div><div class=""><br class=""></div><div class="">#if !swift(&gt;=3.2)<br class="">/* code */</div><div class="">#endif</div><div class=""><br class=""></div><div class="">…when it would be a little easier to grok what’s happening if it were possible to do this:</div><div class=""><br class=""></div><div class=""><div class="">#if swift(&lt;3.2)<br class="">/* code */</div><div class="">#endif</div><div class=""><br class=""></div><div class="">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!).</div><div class=""><br class=""></div><div class="">If I’m reading this correctly (sorry if my interval notation is wrong it’s been a while) the bounds here would be:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(81, 195, 79); background-color: rgb(41, 43, 54);" class=""><span style="color: rgb(231, 232, 235);" class="">&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: rgb(231, 232, 235);" class="">&nbsp;</span>// n &gt;= 4.1</div><div style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(231, 232, 235); background-color: rgb(41, 43, 54);" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #51c34f" class="">// or</span></div><div style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(81, 195, 79); background-color: rgb(41, 43, 54);" class=""><span style="color: #e7e8eb" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span>// 3.3 &gt;= n &lt; 4.0</div><div style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(231, 232, 235); background-color: rgb(41, 43, 54);" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #d38d5d" class="">#if</span> <span style="color: #d38d5d" class="">swift</span>(&gt;=<span style="color: #00aaa3" class="">4.1</span>) || (<span style="color: #d38d5d" class="">swift</span>(&gt;=<span style="color: #00aaa3" class="">3.3</span>) &amp;&amp; !<span style="color: #d38d5d" class="">swift</span>(&gt;=<span style="color: #00aaa3" class="">4.0</span>))</div><div style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(231, 232, 235); background-color: rgb(41, 43, 54);" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #29a09f" class="">print</span>(<span style="color: rgb(222, 58, 60);" class="">"asdf"</span>)</div><div style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(231, 232, 235); background-color: rgb(41, 43, 54);" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #d38d5d" class="">#endif</span></div></div><div><br class=""></div><div>But if it were possible to use &gt; and &lt;, it would read:</div><div><br class=""></div><div><div style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(231, 232, 235); background-color: rgb(41, 43, 54);" class=""><span style="color: #d38d5d" class="">&nbsp; &nbsp; &nbsp; &nbsp; #if</span> (<span style="color: #d38d5d" class="">swift</span>(&gt;=<span style="color: #00aaa3" class="">3.3</span>) &amp;&amp; <span style="color: #d38d5d" class="">swift</span>(<u class="">&lt;</u><span style="color: #00aaa3" class="">4.0</span>)) || <span style="color: #d38d5d" class="">swift</span>(&gt;=<span style="color: #00aaa3" class="">4.1</span>)</div><div style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(231, 232, 235); background-color: rgb(41, 43, 54);" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #29a09f" class="">print</span>(<span style="color: rgb(222, 58, 60);" class="">"asdf"</span>)</div><div style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(231, 232, 235); background-color: rgb(41, 43, 54);" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #d38d5d" class="">#endif</span></div></div><div><br class=""></div><div>(I don’t know why Mail.app is making the &lt; above look like a less than or equal to symbol ≤)</div><div><br class=""></div><div>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’.</div><div><br class=""></div><div>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.</div><div><br class=""></div><div>Hope this helps!</div><div><br class=""></div><div>Alan</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class="">On Jan 5, 2018, at 4:19 PM, Jordan Rose via swift-build-dev &lt;<a href="mailto:swift-build-dev@swift.org" class="">swift-build-dev@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">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 <i class="">compiler?".</i><div class=""><i class=""><br class=""></i></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">#if swift(&gt;=3.2)</div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">// Swift 3.2 (4.0 in compatibility mode)</div><div class="">// Swift 3.3 (4.1 in compatibility mode)</div><div class="">// Swift 4.0</div><div class="">// Swift 4.1</div><div class="">#endif</div><div class=""><br class=""></div><div class="">#if swift(&gt;=3.3)</div><div class="">// Swift 3.3 (4.1 compatibily mode)</div><div class="">// Swift 4.0</div><div class="">// Swift 4.1</div><div class="">// this one is probably not very useful</div><div class="">#endif</div><div class=""><br class=""></div><div class="">#if swift(&gt;=4.0)</div><div class="">// Swift 4.0</div><div class="">// Swift 4.1</div><div class="">#endif</div></blockquote><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">#if ???</blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">// Swift 3.3</blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">// Swift 4.1</blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">#endif</blockquote><div class=""><br class=""></div>I don't think this is going to come up a <i class="">lot,</i>&nbsp;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:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">#if swift(&gt;=4.1) || (swift(&gt;=3.3) &amp;&amp; !swift(&gt;=4.0))</div><div class="">print("new")</div><div class="">#else</div><div class="">print("old")</div><div class="">#endif</div></blockquote><div class=""><br class=""></div>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 <i class="">and</i>&nbsp;run into compatibility issues.&nbsp;<br class=""><div class=""><div class=""><div class=""><div class=""><br class=""></div><div class="">(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.)</div></div></div></div><div class=""><br class=""></div><div class="">Jordan</div></div>_______________________________________________<br class="">swift-build-dev mailing list<br class=""><a href="mailto:swift-build-dev@swift.org" class="">swift-build-dev@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-build-dev<br class=""></div></blockquote></div><br class=""></div></body></html>