[swift-evolution] [RFC] "Library Evolution Support in Swift ('Resilience')"

Drew Crawford drew at sealedabstract.com
Wed Feb 10 18:13:59 CST 2016


This is an amazing document.  I do not understand half of it, but the half I do understand will set software engineering forward ten years.

It will take me a long time to digest all of it, but 2 quick things:

> It is legal to change the implementation of an inlineable function in the next release of the library. However, any such change must be made with the understanding that it may or may not affect existing clients.

I think this is wrong.  Specifically, let's say I have a security bug in my inlineable function.  *Currently*, the industry practice for responding to security issues is "download the new version of the library".  But for inlined functions, this is not good enough to correctly apply the patch.

In my view, "somebody" (the linker, the loader, the runtime... it's all greek to me) should say "hold on a minute, you cannot use the new library version, recompile your code".  Because as long as it appears the new library version installs/works fine, the security fix is falsely assumed to be applied.

Another thing I think we are missing here is versioning the function bodies themselves.  For example (ignore syntax) suppose we have

            
public (1.0) func removeTheCacheFiles() {
      os.rmdir("/path/to/cache")
}

We may evolve this function in two orthogonal ways:

We may develop other cache files as our program grows
We may discover that we forgot to check if the user is allowed by the security policy to remove the cache files.

Therefore we may evolve this function as follows (again, I use pretend syntax):

public (1.0) func removeTheCacheFiles() {
      precondition(userIsAuthorized()) //this change is backported to 1.0
      os.rmdir("/path/to/cache")
      #if 1.1 { //this code only for 1.1-era callers
        os.rmdir("/path/to/cache2")
      }
}

It is important to support this case because very often in server land, certain clients only want to pick up the security fixes (and not, say, new features).  See e.g. this Debian Security FAQ <https://www.debian.org/security/faq#oldversion>, where people spend a huge amount of time backporting security fixes to old versions.

I realize this is not at all the practice in "consumer-grade" applications like iOS/OSX/etc., but it is very entrenched in serverland, and I really think there is value in supporting this at the language level for those people who work in that world.

I think the implementation of this is just to compile all possibilities and just let the client pick the implementation based on the API version.  I realize this may result in larger binaries, but only when the feature is used, so it's opt-in.

Apologies for not using fancy compiler words, I am still trying to grasp the full implications of this amazing paper.

> On Feb 8, 2016, at 8:24 PM, Jordan Rose via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Hi, swift-evolution. We've been making references for a while to "resilience" as a cornerstone of the Swift 3.0 work, the collection of features that allows a library to evolve over time while maintaining binary compatibility. Among other things, this is necessary if we want to stop bundling the Swift standard library with any app that uses Swift, a noted complaint from iOS developers. :-)
> 
> If you're wondering what this is all about, take a look at the prologue for the design document:
> 
>> One of Swift’s primary design goals is to allow efficient execution of code without sacrificing load-time abstraction of implementation.
>> 
>> Abstraction of implementation means that code correctly written against a published interface will correctly function when the underlying implementation changes to anything which still satisfies the original interface. There are many potential reasons to provide this sort of abstraction. Apple’s primary interest is in making it easy and painless for our internal and external developers to improve the ecosystem of Apple products by creating good and secure programs and libraries; subtle deployment problems and/or unnecessary dependencies on the behavior of our implementations would work against these goals.
>> 
>> Our current design in Swift is to provide opt-out load-time abstraction of implementation for all language features. Alone, this would either incur unacceptable cost or force widespread opting-out of abstraction. We intend to mitigate this primarily by designing the language and its implementation to minimize unnecessary and unintended abstraction:
>> 
>> 	• Avoiding unnecessary language guarantees and taking advantage of that flexibility to limit load-time costs.
>> 	• Within the domain that defines an entity, all the details of its implementation are available.
>> 	• When entities are not exposed outside their defining module, their implementation is not constrained.
>> 	• By default, entities are not exposed outside their defining modules. This is independently desirable to reduce accidental API surface area, but happens to also interact well with the performance design.
>> 
>> This last point is a specific case of a general tenet of Swift: the default behavior is safe. Where possible, choices made when an entity is first published should not limit its evolution in the future.
> 
> 
> RFC stands for "request for comments", and that's what this is: I'd appreciate the eager and discriminating eyes of swift-evolution on this model. It is quite long—nearly ten thousand words—and attempts to be fairly precise in describing what is and isn't allowed, so feel free to focus on the parts that interest you most. This isn't a proposal and won't be going through the Swift Evolution Process, but many existing or planned proposals will affect or support the model described here. (There's a list of them at the end of the document.)
> 
> The document is written in ReStructuredText to match the rest of the compiler documentation, but it's using some features from the Sphinx system that GitHub's ReST renderer doesn't support. Consequently, I've put up a rendered form <http://jrose-apple.github.io/swift-library-evolution/>, which I'll update every few days when there are changes. (This is pretty much the same rendering you get from running "make" in the docs/ directory in the Swift repo.) The canonical document is still the one in the Swift repository <https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst>.
> 
> Looking forward to your feedback!
> Jordan
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160210/298d5cda/attachment.html>


More information about the swift-evolution mailing list