One major drawback of splitting Coe library, is that despite having a stable ABI, you break the possibility to include binary frameworks inside an application unless they both link on the same version of libswiftCoreDeprecated.dylib (assuming libswiftCoreDeprecated.dylib has not a stable ABI, else there is no point having it in the first place).
> Le 13 janv. 2018 à 01:43, Ted Kremenek via swift-evolution > <swift-evolution@swift.org> a écrit : > > Hi Chris, > > 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. > > 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. > > 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. > > With that in mind, here are the tradeoffs as I see between scenarios (A) and > (B): > > > (A) Status quo: Keep shipping everything in libswiftCore.dylib > > - 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. > > - 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. > > - We continue to support the deprecated APIs for some time, possibly > indefinitely, even when better alternatives come around. > > (B) Split libswiftCore.dylib into two dylibs, one that gets embedded in the > app bundle > > In the second scenario, we split out the deprecated APIs into a separate > dylib, say libswiftCoreDeprecated.dylib. That solution would have the > following characteristics: > > - Like scenario (A), app bundles would not need to embed libswiftCore.dylib > when running on an OS that had an ABI-stable Standard Library. > > - 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. > > - 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. > > - 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. > > - 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. > > - 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. > > > With these points in mind, both scenarios are (by construction) very similar. > Scenario (B) potentially provides a bit more flexibility in outright > sunsetting deprecated APIs down the road — but only the APIs we deem today > should be on that path. In the future when we decide to deprecate APIs in the > Standard Library we will need to follow the same kind of > deprecation-and-obsoletion path as other binary frameworks in macOS/iOS, > which may mean keeping API implementations around for a very long time just > for the purpose of binary compatibility. > > If you agree with me up to this point, to me this boils down to a tradeoff of > some slightly increased opportunity to sunset some APIs in the future for a > slight reduction in size of the Standard Library today (as it ships in the > OS). Most apps that don’t use these APIs won’t care either way, because even > if we go with scenario B if they don’t use one of the deprecated APIs they > will essentially be in scenario A (and thus get the benefit of using a > Standard Library from the OS). In scenario B, those apps that use the > deprecated APIs will be slightly punished with slightly increased app bundle > size and startup time. Further, these APIs really can’t be deprecated right > now (in terms of marking them deprecated in the module) until we have actual > alternatives, so for the users that really want to use Mirrors today (which I > agree may be small) that is the main tool they have to obtain that > functionality. Such users will pay a cost — albeit probably pretty minor — > in scenario B. > > 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). > > Do these observations align with what you are proposing, or am I missing a > critical detail? > > Ted > >> On Jan 11, 2018, at 11:56 AM, Chris Lattner <clatt...@nondot.org >> <mailto:clatt...@nondot.org>> wrote: >> >>> On Jan 11, 2018, at 12:01 AM, Ted Kremenek <kreme...@apple.com >>> <mailto:kreme...@apple.com>> wrote: >>>> The nice thing about this is that only people who use these things would >>>> have to pay the cost, and you can directly message this by deprecating all >>>> the stuff in it. Think about it as an overlay for the Swift standard >>>> library :-) >>> >>> Hi Chris, >>> >>> Even if we split the APIs into two sets, with an “ABI unstable” subset, we >>> are still going to “carry round these ’suboptimal APIs’” because clients >>> are using them today and those APIs — without an active plan to remove them >>> — *are* a part of the Standard Library. We’ve past the point in Swift >>> where we can just rip them out (you said so yourself in a follow up email). >> >> Who is “we” and how do you define carry? >> >> I think you’re saying that they will remain part of the swift project (in >> the “SwiftDeprecated” module) for effectively ever. If so, I agree, and >> that’s the point. The point is that the code can continue to exist and >> service the few people who need it (and will become even fewer over the >> years) without causing *harm* to the Swift ecosystem over the near or long >> term. That’s the feature. >> >>> It feels to me that the main advantage of the overlay is a solution to >>> remove out pieces of the Standard Library that will be used in practice >>> less, and thus clients don’t “pay the cost” when they don’t use them. >> >> Yes, exactly. >> >>> But I think we should be honest about what that “cost” actually is, as >>> these APIs aren’t going away right now. These suboptimal APIs will stay >>> around at least until better ones are created, and even then some existing >>> clients will want to rely on the existing suboptimal APIs anyway even if >>> others want to take advantage of newer, better APIs and idioms. >> >> I’m not sure what you mean. I’m talking about two things specifically: >> >> 1) APIs that are already deprecated and have replacements. The deprecated >> version goes in this library, avoid carrying them around forever. >> >> 2) APIs that are used by extremely narrow audiences, which were added >> without much consideration and that have not been redesigned since Swift 1. >> Mirror’s are an example of this. I’m arguing that these should be moved to >> this SwiftDeprecated module - but not actually deprecated until a >> replacement exists. >> >> I don’t see how this is bad for anyone, and I think this provides a >> significant process improvement compared to your current approach, which >> forces you to lock down APIs now without careful consideration just because >> they are not “important enough”. >> >>> The main cost I see here that we save by having an “overlay for the >>> Standard library" is code size. >> >> I don’t understand this point. >> >>> On macOS/iOS it is true that applications embed a copy of the Standard >>> Library within them and thus pay a real cost in the Standard Library’s >>> actually payload size in their own app. However, the only reason that is >>> necessary today is because we don’t have ABI stability. With ABI >>> stability, other options for shipping the Standard Library — such as >>> shipping it in the OS — become possible, and thus the burden of shouldering >>> that “cost” of code size shifts around. Then the tradeoffs of having an >>> overlay for the Standard Library are different. In a world with ABI >>> stability, is it better to have a Standard Library "overlay" that only some >>> clients use, and embed within their application bundle, than just eat that >>> cost in the Standard Library to be shared by potentially multiple clients >>> installed on a system? I think it really comes down to the numbers. In >>> that case, are we really just talking about Mirrors? I haven’t run the >>> numbers here, but my intuition tells me we are talking about a relatively >>> small code size impact overall. >> >> This comment doesn’t make a lot of sense to me, perhaps we’re talking across >> each other. The point of the design that I’m advocating for is that all >> apps (that deploy to iOS-next or later) get a immediate improvement from abi >> stability: the vast majority of the standard library is not put into their >> app bundle. Further, the vastly most common apps - those that are not using >> mirrors or deprecated APIs, also do not include the SwiftDeprecated module. >> >> Only the tiny minority of apps that do use these APIs would have a copy of >> SwiftDeprecated in their app dylib, but they have a path to fix that, and >> they would still see a huge improvement from the bulk of the standard >> library being out of their app bundle. >> >>> >>> There’s also other potential performance implications from doing this >>> split. >> >> This doesn’t make sense to me. We’re not talking about taking comonly used >> apis here. Mirrors are not performance sensitive at all, and neither are >> deprecated wrappers of renamed APIs. >> >>> Being able to have the Standard Library be in the OS has potential major >>> implications on the startup time of Swift applications. >> >> It is great for app developers to have an incentive to stop using deprecated >> APIs! :-) >> >>> Can you elaborate a bit more on the specific “cost” factors you are using >>> when proposing to have a Standard Library overlay? >> >> I think it is possible that you’re reading too much into the “overlay" word >> here, so ignore that. The design I’m proposing is really simple: >> >> 1. The vast majority of the standard library goes into the OS. This >> includes all the string, array, and other stuff people use. >> 2. The deprecated wrappers and obscure APIs go into a new module, and that >> module doesn’t go into the OS. Only people that use it pay to cost. >> >> This isn’t particularly complicated, if give you new ways to manage the >> process of stdlib ABI stability, and I don’t see the downside. >> >> -Chris >> >> >> > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution