<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><blockquote type="cite" class="">The review of "SE-0075: Adding a Build Configuration Import Test" begins now and runs through May 16. The proposal is available here:<br class=""></blockquote><div><blockquote type="cite" class=""><div class=""><div class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0075-import-test.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0075-import-test.md</a></div></div></blockquote><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class=""><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>* What is your evaluation of the proposal?<br class=""></div></div></blockquote><div><br class=""></div><div>+1, I think it's a welcome change that improves modularity between libraries.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>* Is the problem being addressed significant enough to warrant a change to Swift?<br class=""></div></div></blockquote><div><br class=""></div><div>Yes.</div><div><br class=""></div><div>There's another real problem that this feature solves which I couldn't see mentioned in the proposal: adding protocol conformances to optional dependencies. Suppose a library named Frobnication defined a protocol `<font face="Menlo" class=""><span style="font-size: 11px;" class="">Frobnicatable</span></font>`, with some known conformances:</div><div><br class=""></div><div><font face="Menlo" color="#919191" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; // module Frobnication</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; public protocol Frobnicatable {</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp; mutating func frobnicate()</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; }</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; extension String : Frobnicatable { ... }</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; extension Frob : Frobnicatable { ... }</span></font></div><div><br class=""></div><div>Now, suppose something in a 3rd party library called Knobs was also clearly `<font face="Menlo" class=""><span style="font-size: 11px;" class="">Frobnicatable</span></font>` but `<font face="Menlo" class=""><span style="font-size: 11px;" class="">canImport</span></font>` didn't exist. The community would have to pick from the following poorly scaling alternatives:</div><div><br class=""></div><div>#1) Either Frobnication would require and import Knobs as its dependency and add the conformances,</div><div>#2) or vice versa, Knobs would&nbsp;pull Frobnication as its dependency,</div><div>#3) or everybody using both libraries would need to define the conformances theirselves,</div><div>#4) or someone would need to maintain a "KnobsFrobnication" library for the sole purpose of defining the said protocol conformances.</div><div><br class=""></div><div>* * *</div><div><br class=""></div><div><b class="">With `</b><font face="Menlo" class=""><span style="font-size: 11px;" class=""><b class="">canImport</b></span></font><b class="">`</b>, on the other hand, we get two good options:</div><div><br class=""></div><div>#5) Either Frobnication checks `<font face="Menlo" class=""><span style="font-size: 11px;" class="">#if canImport(Knobs)</span></font>` and conditionally adds the conformances,</div><div>#6) or&nbsp;Knobs&nbsp;checks if it `<font face="Menlo" class=""><span style="font-size: 11px;" class="">canImport(Frobnication)</span></font>` and conditionally adds the conformances to any suitable types it defines (which is what any new libraries that the author of Frobnication wasn't aware of could do in the future).</div><div><br class=""></div><div>* * *</div><div><br class=""></div><div><b class="">But there remains one issue</b> that there's no clear path for moving conformance definitions from one library into the other one day. This proposal could be improved by allowing to <b class="">check for library versions</b> too! If similarly to `<font face="Menlo" class=""><span style="font-size: 11px;" class="">#if swift(&gt;=2.2)</span></font>`, we could check `<font face="Menlo" class=""><span style="font-size: 11px;" class="">#if canImport(Knobs &gt;= @2.10.0)</span></font>`, then the authors of&nbsp;Knobs&nbsp;and Frobnication could organise an orchestrated move of conformance definitions from one library into another. Before the move, Knobs&nbsp;2.9.x would have defined:</div><div><br class=""></div><div><font face="Menlo" color="#919191" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; // module Knobs 2.9.x</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; #if canImport(Frobnication)</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; import Frobnication</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; extension Knob : Frobnicatable { ... }</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; #endif</span></font></div><div><br class=""></div><div>Preparing for the move, a new version of Frobnication could introduce the conformance thusly:</div><div><br class=""></div><div><font face="Menlo" color="#919191" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; // module Frobnication 1.7.3</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; #if canImport(Knobs <b class="">&gt;= @2.10.0</b>) <font color="#919191" class="">// *) see note below</font></span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; import Knobs</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; extension Knob : Frobnicatable { ... }</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; #endif</span></font></div><div><br class=""></div><div>Then, Knobs could gracefully sunset its conformance definitions beginning from the 2.10.0 release:</div><div><br class=""></div><div><font face="Menlo" color="#919191" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; // module Knobs 2.10.0</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; #if canImport(Frobnication <b class="">&lt; @1.7.3</b>) <font color="#919191" class="">// &lt;-&nbsp;</font></span></font><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">Only added version constraint here.</span></div><div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; import Frobnication</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; extension Knob : Frobnicatable { ... }</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; #endif</span></font></div><div class=""><br class=""></div><div><font color="#919191" class="">*) I'm not sold to any specific syntax, but we could e.g. use the `@` prefix to distinguish <i class="">version number literals</i> like `@1`, `@0.10` and `@0.10.0` from similar but differently behaving numeric literals.</font></div><div><br class=""></div><div class="">In any case, even with just `<font face="Menlo" class=""><span style="font-size: 11px;" class="">canImport(module)</span></font>`, we can do a lot better than currently.</div></div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>* Does this proposal fit well with the feel and direction of Swift?<br class=""></div></div></blockquote><div><br class=""></div><div>Yes.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>* If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?<br class=""></div></div></blockquote><div><br class=""></div><div>Yes, like mentioned in the proposal, it's very similar to the `<font face="Menlo" class=""><span style="font-size: 11px;" class="">__has_import(&lt;path/to/import.h&gt;)</span></font>` macro in Clang. I'm not fully familiar with the design space in Haskell, but it seems to me instead of using something similar to `<font face="Menlo" class=""><span style="font-size: 11px;" class="">canImport</span></font>` Haskellers tend to favour the approach I listed above as alternative #4 (e.g.&nbsp;<a href="https://github.com/lens/lens-aeson/" class="">https://github.com/lens/lens-aeson/</a>&nbsp;brings the lens and aeson libraries together).</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>* How much effort did you put into your review? A glance, a quick reading, or an in-depth study?<br class=""></div></div></blockquote></div><br class=""><div class="">Quick reading.</div><div class=""><br class=""></div><div class="">— Pyry</div><div class=""><br class=""></div></body></html>