Sorry if this should be clear already, but are you suggesting that @patch would 
allow patching of final or sealed types thus making them more palatable as 
defaults?  This would surprise me, but if that is not what you are suggesting I 
don't follow how it relates to the final / sealed discussion.

Matthew

Sent from my iPad

> On Dec 31, 2015, at 1:13 PM, Joe Groff via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> A lot of the discussion around the final/sealed-by-default issue focused on 
> the ability in ObjC to extend frameworks or fix bugs in unforeseen ways. 
> Framework developers aren't perfect, and being able to patch a broken 
> framework method can be the difference between shipping and not. On the other 
> hand, these patches become compatibility liabilities for libraries, which 
> have to contend not only with preserving their own designed interface but all 
> the undesigned interactions with shipping apps based on those libraries. The 
> Objective-C model of monkey-patchable-everything has problems, but so does 
> the buttoned-down everything-is-static C++ world many of us rightly fear. 
> However, with the work we're putting into Swift for resilience and strong 
> versioning support, I think we're in a good position to try to find a 
> reasonable compromise. I'd like to sketch out a rough idea of how that might 
> look. Public interfaces fundamentally correspond to one or more dynamic 
> library symbols; the same resilience that lets a new framework version 
> interact with older apps gives us an opportunity to patch resilient 
> interfaces at process load time. We could embrace this by allowing 
> applications to provide `@patch` implementations overriding imported 
> non-fragile public APIs at specific versions:
> 
> import Foundation
> 
> extension NSFoo {
>   @patch(OSX 10.22, iOS 17)
>   func foo() { ... }
> }
> 
> By tying the patch to a specific framework version, we lessen the 
> compatibility liability for the framework; it's clear that, in most cases, 
> the app developer is responsible for testing their app with new framework 
> versions to see if their patch is still needed with each new version. Of 
> course, that's not always possible—If the framework developer determines 
> during compatibility testing that their new version breaks a must-not-break 
> app, and they aren't able to adopt a fix on their end for whatever reason (it 
> breaks other apps, or the app's patch is flawed), the framework could declare 
> that their new version accepts patches for other framework versions too:
> 
> // in Foundation, OSX 10.23
> public class NSFoo {
>   // Compatibility: AwesomeApp patched the 10.22 version of NSFoo.foo.
>   // However, RadicalApp and BodaciousApp rely on the unpatched 10.22 
> behavior, so
>   // we can't change it.
>   @accepts_patch_from(AwesomeApp, OSX 10.22)
>   public func foo() { ... }
> }
> 
> A sufficiently smart dynamic linker could perhaps resolve these patches at 
> process load time (and probably summarily reject patches for dylibs loaded 
> dynamically with dlopen), avoiding some of the security issues with arbitrary 
> runtime patching. For public entry points to be effectively patchable, we'd 
> have to also avoid any interprocedural optimization of the implementations 
> within the originating module, so there is a performance cost to allowing 
> this patching by default. Sufficiently mature (or arrogant) interfaces could 
> perhaps declare themselves "unpatchable" to admit IPO within their own 
> module. (Note that 'fragile' interfaces which admit cross-module inlining 
> would inherently be unpatchable, and those are likely to be the most 
> performance-sensitive interfaces to begin with.)
> 
> -Joe
> 
> _______________________________________________
> 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

Reply via email to