<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 8, 2016, at 19:17 , Joe Groff &lt;<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><br class=""><blockquote type="cite" class="">On Feb 8, 2016, at 6:47 PM, Charles Srstka via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""><blockquote type="cite" class="">On Feb 8, 2016, at 8:24 PM, Jordan Rose via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class="">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. :-)<br class=""><br class="">If you're wondering what this is all about, take a look at the prologue for the design document:<br class=""><br class=""><blockquote type="cite" class="">One of Swift’s primary design goals is to allow efficient execution of code without sacrificing load-time abstraction of implementation.<br class=""><br class="">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.<br class=""><br class="">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:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Avoiding unnecessary language guarantees and taking advantage of that flexibility to limit load-time costs.<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Within the domain that defines an entity, all the details of its implementation are available.<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• When entities are not exposed outside their defining module, their implementation is not constrained.<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• 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.<br class=""><br class="">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.<br class=""></blockquote><br class="">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.)<br class=""><br class="">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, 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.<br class=""><br class="">Looking forward to your feedback!<br class="">Jordan<br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></blockquote><br class="">I noticed this note in the document:<br class=""><br class=""><blockquote type="cite" class="">Note<br class="">Swift 2’s implementation of default values puts the evaluation of the default value expression in the library, rather than in the client like C++ or C#. We plan to change this.<br class=""></blockquote><br class="">What is the reasoning behind this? Keeping the default value in the library seems more resilient; if the default value changes, clients will get the new behavior without requiring a recompile, thus matching the behavior that you’d get if you implemented the same thing via a method with fewer arguments (as you’d have done in Objective-C). This seems far preferable to hard-coding all the default values in the client, IMO.<br class=""></blockquote><br class="">Abstracting default values from the client limits resilience in other, more obnoxious ways. In particular, it means you can't *introduce* new defaulted parameters on published APIs without a deployment target limitation, since the entry point for the default argument evaluator will be missing in older versions. We figured that instantiating the default argument on the client side is more in line with users' expectations in what resilience constraints it imposes. In many cases, you'll have the resilinece you want at a different level; for example, in the common case of an option set where the default is 'all options', evaluating 'func foo(options: Options = .all)' is still resilient if 'Options.all' is.<br class=""></div></div></blockquote></div><br class=""><div class="">In addition, it's less resilient than you think it is (and than we thought it would be when we introduced it). The library author still needs to document what the default behavior is <i class="">anyway,</i>&nbsp;so that users know if they want it, and they need to be very careful in changing existing programs, so that they don't break anyone who was depending on the old behavior, and they need to make sure that anybody who supplied the same value explicitly really does&nbsp;<i class="">not</i>&nbsp;want the new behavior.</div><div class=""><br class=""></div><div class="">After all that, it turns out there aren't really any places where you can safely change the value of a default parameter anyway.</div><div class=""><br class=""></div><div class="">Jordan</div><div class=""><br class=""></div><div class="">P.S. Credit to DaveA for convincing the rest of us. Or me, at least.</div></body></html>