<div dir="ltr">Alternatively, from a different perspective, rather than adding a new ABI-unstable library that gets bundled with apps, another way to look at it is that we already *have* an ABI-unstable library that gets bundled with apps. So we can instead think about introducing a new library with a stable ABI, which can be distributed with the OS.<div><br></div><div>That way, as each piece of the existing standard library gets finalized, we can move it into the new ABI-stable library. Some pieces (eg. Mirror) will never make the jump and can be phased out eventually. And when future proposals make additions to the standard library, they can begin life in the original, existing, non-ABI-stable library.</div><div><br></div><div>The net effect is the same as what we have been discussing, but a shift in viewpoint makes it clear that the ABI-stable library is the new thing we are adding, and the existing standard library can continue to serve a valuable purpose going forward.</div><div><br></div><div>Nevin</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jan 14, 2018 at 9:04 PM, Ted Kremenek via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
<br>
&gt; On Jan 12, 2018, at 11:23 PM, Chris Lattner &lt;<a href="mailto:clattner@nondot.org">clattner@nondot.org</a>&gt; wrote:<br>
&gt;<br>
&gt; On Jan 12, 2018, at 4:43 PM, Ted Kremenek &lt;<a href="mailto:kremenek@apple.com">kremenek@apple.com</a>&gt; wrote:<br>
&gt;&gt; Hi Chris,<br>
&gt;&gt;<br>
&gt;&gt; Instead of responding to each of your point bit-by-bit, I’ll try a different tactic to explain my reasoning — which may be wrong — by explaining how I see things top down with the tradeoffs they incur.  I’m going to say a bunch of things I know *you* know, but others are on this thread and I’ll state things for end-to-end clarity.<br>
&gt;<br>
&gt; Sounds good.<br>
&gt;<br>
&gt;&gt; It seems to me that we are talking about two possible scenarios: (1) the status quo of keeping everything in libswiftCore.dylib or (2) splitting libswiftCore.dylib into two dylibs, one which includes some of the “deprecated” APIs.  I’ll enumerate what I think are the tradeoffs/benefits we will see with both scenarios, and see where the mismatch in our “talking past each other” is happening.<br>
&gt;<br>
&gt; Right.<br>
&gt;<br>
&gt;&gt; In both cases (A) and (B), with ABI stability the Standard Library has the option to ship in the OS.  Thus applications using Swift on (say) iOS would no longer need to include libswiftCore.dylib in the app when running on an OS that shipped with the Standard Library.<br>
&gt;<br>
&gt; Right.  Please keep in mind that both approaches also eliminate all the overlay dylibs for those apps, and both approaches put the vast majority of the stdlib code into the OS as well.  The ‘deprecated’ dylib is probably going to be comparatively small.<br>
&gt;<br>
&gt;&gt; With that in mind, here are the tradeoffs as I see between scenarios (A) and (B):<br>
&gt;&gt;<br>
&gt;&gt; (A) Status quo: Keep shipping everything in libswiftCore.dylib<br>
&gt;&gt;<br>
&gt;&gt; - Applications running on an OS with the Standard Library would no longer have *any* of the currently libswift*.dylib’s embedded inside the application bundle because they would just use the one in the OS.<br>
&gt;<br>
&gt; Right.<br>
&gt;<br>
&gt;&gt; - One benefit of using libswift*.dylibs in the OS as opposed to those embedded inside the app bundle is that there is a non-neglible startup time improvement, as the code signing verification that happens when an app launches would be faster as it would not need to verify each of these dylibs that were previously embedded in the app.  We should consider this the new baseline for app startup time for an app running on an OS with an ABI stable Standard Library.<br>
&gt;<br>
&gt; This happens with both models.  Refer back to the dyld optimization WWDC talk by Nick and Louis 2-3 years ago.  The big problem with Swift for startup time is that it adds half a dozen (or more) dylibs to your app bundle.  In the talk they make it clear that adding a single dylib is not a big deal, it is adding a bunch of dylibs that is the problem, particularly if they have interdependencies between them.<br>
<br>
</span>Right — it is the large volume of dylibs that is the problem.<br>
<span class=""><br>
&gt;<br>
&gt; Neither approach presents this performance problem.<br>
<br>
</span>Agreed — in practice neither scenario is much different.<br>
<span class=""><br>
&gt;<br>
&gt; Further, if it were important to solve this startup time problem, it is straight-forward to solve it for apps that do want to deploy backward (which will be almost all of them in NMOS).  You’d do this by merging all the dylibs into a single one in the app bundle instead of leaving them to be independently resolved at load time.<br>
&gt;<br>
&gt;&gt; - We continue to support the deprecated APIs for some time, possibly indefinitely, even when better alternatives come around.<br>
&gt;<br>
&gt; Agreed.<br>
&gt;<br>
&gt;&gt; (B) Split libswiftCore.dylib into two dylibs, one that gets embedded in the app bundle<br>
&gt;&gt;<br>
&gt;&gt; In the second scenario, we split out the deprecated APIs into a separate dylib, say libswiftCoreDeprecated.dylib.  That solution would have the following characteristics:<br>
&gt;&gt;<br>
&gt;&gt; - Like scenario (A), app bundles would not need to embed libswiftCore.dylib when running on an OS that had an ABI-stable Standard Library.<br>
&gt;&gt;<br>
&gt;&gt; - Compared to scenario (A), the OS shipping the Standard Library would have a slightly smaller libswiftCore.dylib that didn’t carry the bits for the deprecated APIs.  This would be a benefit in the code size for the OS, but not for the app itself.<br>
&gt;<br>
&gt; The code size is small so it doesn’t matter much either way,<br>
<br>
</span>Agreed.<br>
<span class=""><br>
&gt; but this actually is an advantage for the average app.  Part of the point of this is that most apps don’t use this stuff, so they wouldn’t include the dylib at all.  There is no cost for them in either launch time or size.<br>
&gt;<br>
&gt; To pick on Mirrors, the one example someone came up with is an API used by the swift on server community.  I haven’t heard of anyone using them in an iOS app (but of course I’m sure there is someone somewhere doing it :-)<br>
&gt;<br>
&gt;&gt; - Any app using a deprecated API we put into libswiftCoreDeprecated.dylib (e.g., Mirrors) would need to embed libswiftCoreDeprecated.dylib inside their app bundle.  Compared to the new baseline I mentioned in (A), such apps would have a launch time regression once they started using any API in the libSwiftCoreDeprecated.dylib because code signing would need to verify the dylib, just like it does today with the libswiftCore.dylib that is embedded in every application.  They would also be slightly larger because the app bundle has the burden of hosting libswiftCoreDeprecated.dylib, instead of compared to scenario (A) where the implementations of the deprecated APIs are hosted by the libswiftCore.dylib that ships in the OS.<br>
&gt;<br>
&gt; The launch time comes from dyld, not code signing, but yes they would pay a very small cost.<br>
<br>
</span>Yes, you’re right it is dyld.  For some reason I was thinking about code signing.<br>
<span class=""><br>
&gt;  Again, I’d strongly recommend brushing up on nick + louis&#39; WWDC talk that discusses this.<br>
&gt;<br>
&gt; More to the point though, it is *good* that there is some (small) pressure for people to stop using APIs that are deprecated in Swift 5 and earlier.  This is a one time opportunity. :-)<br>
<br>
</span>Perhaps.  It feels (to me) like a rather minor opportunity considering we need to still keep these APIs around and maintain them for some (perhaps long) period of time.<br>
<span class=""><br>
&gt;<br>
&gt;&gt; - Because of binary compatibility concerns, after Swift 5 we would *never* be able to “take out” any further APIs from libswiftCore.dylib and put them in libswiftCoreDeprecated.dylib.  This factorization can only happen once.<br>
&gt;<br>
&gt; Correct, though Xiaodi’s point about gradually easing new APIs in with a similar approach is really really interesting and could be profound.<br>
<br>
</span>Absolutely — it’s an interesting idea, but also orthogonal to this one.  I’d prefer to separate that into a different discussion as that one involves a different set of concerns and parties interested in that discussion.<br>
<span class=""><br>
&gt;<br>
&gt;&gt; - There is some slight additional complexity added to the compiler and build system to support this spit of the Standard Library into multiple dylibs.  It’s not a huge concern but it does exist and it is not free both in terms of implementing and maintaining.<br>
&gt;<br>
&gt; Sure, but it also greatly eliminates the pressure to achieve perfection for a lot of API that simply isn’t important enough to fret that much about.  This pays for itself in schedule time.<br>
<br>
</span>To be honest I don’t see how it helps *that* much, and we may end up just disagreeing here on the optics.  Since we have to keep these APIs around in some way, regardless of whether or not we are happy with them, I don’t see how it helps eliminate pressure.  I’m not that greatly concerned about burning a small bit of space into the libswiftCore.dylib for some APIs we hope to effectively sunset in the (unforeseeable) future.  OTOH, there are plenty of things with ABI stability that I am concerned get done, which is why efforts are focused on those.<br>
<span class=""><br>
&gt;<br>
&gt;&gt; - We continue to support the deprecated APIs for some time, possibly indefinitely, even when better alternatives come around.  We *may* be able to completely sunset these APIs by having a future version of the Swift compiler simply refuse to build projects that use the deprecated (now obsoleted) APIs.  At that point, these apps need to move to using the newer API alternatives, or not upgrade to using a new Swift compiler.<br>
&gt;<br>
&gt; Right: source compatibility isn’t a forever thing, even for existing Objective-C APIs vended by apple.  Giving people (e.g.) 3 years to migrate and remove them would probably be fine.  The key thing is that you never break *already shipped apps*, you only make more work for people who are actively maintaining/updating their app.<br>
<br>
</span>Agreed.<br>
<span class=""><br>
&gt;<br>
&gt;&gt; With these points in mind, both scenarios are (by construction) very similar.<br>
&gt;<br>
&gt; I disagree, because I think you’re misunderstanding the performance impact of adding exactly one dylib to an app bundle.  How many dylibs does Swift 4 typically add to an app?  It’s probably up to 8 or more.<br>
<br>
</span>I agree that the launch time cost of a single dynamic library is small.  My concern then is on the impact on people time of doing this factorization, and adding the needed logic to the build system and compiler to support it.  It’s not insurmountable, but feels like a “nice to have” compared to other tasks which are clearly quite urgent for ABI stability.  If we run out of urgent things to do, I can see considering doing this.<br>
<span class=""><br>
&gt;<br>
&gt; 1 dylib isn’t a problem, check with Nick and Louis.<br>
&gt;<br>
&gt;&gt; I have not done the measurements of the impact in code size to the Standard Library of removing Mirrors, but I hypothesize it is relatively modest (I will look at verifying this hypothesis).<br>
&gt;<br>
&gt; I agree.  The major motivation from my side isn’t the code size reduction, it is that we’ll have a better and brighter future with more clarity and less weird cruft left over - like the “DictionaryLiteral” type that sparked this whole thread.  Have you looked at it?  It’s crazy. :-)<br>
<br>
</span>I think a bright future is still possible in either scenario.  >From what I can tell, if we don’t do anything, in the worst case there is some baggage left in libswiftCore.dylib for the purposes of binary compatibility with older apps.  We still are left with the opportunity to deprecate those APIs in the future even if we can’t rip those symbols out now.<br>
<div class="HOEnZb"><div class="h5">______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
</div></div></blockquote></div><br></div>