Regards (From mobile)
> On May 20, 2016, at 6:52 PM, Matthew Johnson via swift-evolution > <[email protected]> wrote: > > >> On May 20, 2016, at 11:43 AM, Brandon Knope <[email protected]> wrote: >> >> From the compilers/runtimes perspective why couldn't the declaration >> automatically be included in the main protocol definition as if it was >> defined there? > > That has been discussed as a possible solution but introduces implementation > complexity. I believe core team members have commented on the idea in the > past. I don’t recall the details but you should be able to find the > discussions in the archives if you’re interested. > Not to mention the security risk it represents.... yeah!!! an apple provided official way to patch any dylib during load time. >> >> Brandon >> >>> On May 20, 2016, at 12:21 PM, Matthew Johnson via swift-evolution >>> <[email protected]> wrote: >>> >>> >>>> On May 20, 2016, at 11:17 AM, Austin Zheng via swift-evolution >>>> <[email protected]> wrote: >>>> >>>> I almost want to propose forbidding methods in protocol extensions unless >>>> they're also a requirement in the protocol itself, but I don't think that >>>> would fly. >>> >>> That would prevent us from adding extension methods to protocols declared >>> in modules we depend on. This is way to useful to throw away. >>> >>>> >>>> Austin >>>> >>>>> On May 20, 2016, at 5:56 AM, Fabian Ehrentraud via swift-evolution >>>>> <[email protected]> wrote: >>>>> >>>>> Hi, >>>>> >>>>> there's been a little discussion about static vs. dynamic dispatch on >>>>> this mailing list, and there is a good post about the pitfalls when using >>>>> attributes defined in extensions [1]. >>>>> >>>>> Having run into this myself during development, is there a plan on how to >>>>> reduce the pitfalls in future versions of Swift? >>>>> >>>>> - Fabian >>>>> >>>>> >>>>> [1] >>>>> https://developer.ibm.com/swift/2016/01/27/seven-swift-snares-how-to-avoid-them/ >>>>> >>>>>> Sorry, I understand and appreciate your pragmatism. Right now it feels >>>>>> very much like a fight to the ideological death between POP and OOP and >>>>>> it may get really bad results this way. >>>>>> >>>>>> Sent from my iPhone >>>>>> >>>>>> On 4 Mar 2016, at 08:58, Brent Royal-Gordon <brent at architechies.com> >>>>>> wrote: >>>>>> >>>>>> >> Brent, why is dynamic dispatching for protocol extension default >>>>>> >> implementations wrong in your mind? Wouldn't you agree that when >>>>>> >> static dispatching introduces such a side effect that it should not >>>>>> >> be automatically applied and perhaps a keyword should be added if you >>>>>> >> really wanted static dispatching nonetheless? >>>>>> >> >>>>>> >> I think that code execution should not be affected by type casting, >>>>>> >> it feels like a very confusing part of the language. >>>>>> > >>>>>> > I don't think dynamic dispatch is wrong; I think it's a large and >>>>>> > technically challenging change. So in the spirit of incrementalism, I >>>>>> > was trying to make cautious proposals which kept existing semantics >>>>>> > intact but made them clearer, in preparation for perhaps eventually >>>>>> > introducing dynamic dispatch. (Basically, I suggested that >>>>>> > non-overridable protocol extension members should be marked `final` >>>>>> > and it should be illegal to shadow them.) >>>>>> > >>>>>> > But the feedback I got indicated that most people wanted a more >>>>>> > aggressive proposal which introduced dynamic dispatch immediately. >>>>>> > That's much harder to propose because it touches on all sorts of >>>>>> > runtime implementation details I know nothing about, so I didn't try >>>>>> > to draft a proposal. >>>>>> > >>>>>> > (You are, perhaps inadvertently, currently demonstrating exactly what >>>>>> > happened in those previous threads!) >>>>>> > >>>>>> > -- >>>>>> > Brent Royal-Gordon >>>>>> > Architechies >>>>>> > >>>>> >>>>>> > On Dec 11, 2015, at 8:56 PM, Kevin Ballard via swift-evolution >>>>>> > <swift-evolution at swift.org> wrote: >>>>>> > >>>>>> > You think that Swift prefers virtual dispatch. I think it prefers >>>>>> > static. >>>>>> > >>>>>> > I think what's really going on here is that _in most cases_ there's no >>>>>> > observable difference between static dispatch and virtual dispatch. If >>>>>> > you think of Swift as an OOP language with a powerful value-typed >>>>>> > system added on, then you'll probably think Swift prefers virtual >>>>>> > dispatch. If you think of Swift as a value-typed language with an OOP >>>>>> > layer added, then you'll probably think Swift prefers static dispatch. >>>>>> > In reality, Swift is a hybrid language and it uses different types of >>>>>> > dispatch in different situations as appropriate. >>>>>> >>>>>> (emphasis mine) >>>>>> >>>>>> I know that this is a bit philosophical, but let me suggest a “next >>>>>> level down” way to look at this. Static and dynamic are *both* great >>>>>> after all, and if you’re looking to type-cast languages, you need to >>>>>> consider them both in light of their semantics, but also factor in their >>>>>> compilation strategy and the programmer model that they all provide. >>>>>> Let me give you some examples, but keep in mind that this is a narrow >>>>>> view and just MHO: >>>>>> >>>>>> 1. C: Static compilation model, static semantics. While it does provide >>>>>> indirect function pointers, C does everything possible to punish their >>>>>> use (ever see the non-typedef'd prototype for signal(3/7)?), and is >>>>>> almost always statically compiled. It provides a very “static centric” >>>>>> programming model. This is great in terms of predictability - it makes >>>>>> it trivial to “predict” what your code will look like at a machine level. >>>>>> >>>>>> 2. Javascript: Completely dynamic compilation model, completely dynamic >>>>>> semantics. No one talks about statically compiling javascript, because >>>>>> the result of doing so would be a really really slow executable. >>>>>> Javascript performance hinges on dynamic profile information to be able >>>>>> to efficiently execute a program. This provides a very “dynamic >>>>>> centric” programming model, with no ability to understand how your code >>>>>> executes at a machine level. >>>>>> >>>>>> 3. C++: C++ is a step up from C in terms of introducing dynamism into >>>>>> the model with virtual functions. Sadly, C++ also provides a hostile >>>>>> model for static optimizability - the existence of placement new >>>>>> prevents a lot of interesting devirtualization opportunities, and >>>>>> generally makes the compiler’s life difficult. OTOH, like C, C++ >>>>>> provides a very predictable model: C++ programmers assume that C >>>>>> constructs are static, but virtual methods will be dynamically >>>>>> dispatched. This is correct because (except for narrow cases) the >>>>>> compiler has to use dynamic dispatch for C++ virtual methods. The good >>>>>> news here is that its dynamism is completely opt in, so C++ preserves >>>>>> all of the predictability, performance, and static-compilability of C >>>>>> while providing a higher level programming model. If virtual methods >>>>>> are ever actually a performance problem, a C++ programmer has ways to >>>>>> deal with that, directly in their code. >>>>>> >>>>>> 4. Java: Java makes nearly "everything" an object (no structs or other >>>>>> non-primitive value types), and all methods default to being “virtual” >>>>>> (in the C++ sense). Java also introduces interfaces, which offer an >>>>>> added dimension on dynamic dispatch. To cope with this, Java assumes a >>>>>> JIT compilation model, which can use dynamic behavior to de-virtualize >>>>>> the (almost always) monomorphic calls into checked direct calls. This >>>>>> works out really well in practice, because JIT compilers are great at >>>>>> telling when a program with apparently very dynamic semantics actually >>>>>> have static semantics in practice (e.g. a dynamic call has a single >>>>>> receiver). OTOH, since the compilation model assumes a JIT, this means >>>>>> that purely “AOT” static compilers (which have no profile information, >>>>>> no knowledge of class loaders, etc) necessarily produce inferior code. >>>>>> It also means that Java doesn’t “scale down” well to small embedded >>>>>> systems that can’t support a JIT, like a bootloader. >>>>>> >>>>>> 5) Objective-C: Objective-C provides a hybrid model which favors >>>>>> predictability due to its static compilation model (similar in some ways >>>>>> to C++). The C-like constructs provide C-like performance, and the >>>>>> “messaging” constructs are never “devirtualized”, so they provide very >>>>>> predictable performance characteristics. Because it is predictable, if >>>>>> the cost of a message send ever becomes an issue in practice, the >>>>>> programmer has many patterns to deal with it (including "imp caching", >>>>>> and also including the ability to define the problem away by rewriting >>>>>> code in terms of C constructs). The end result of this is that >>>>>> programmers write code which use C-level features where performance >>>>>> matters and dynamicism doesn’t, but use ObjC features where dynamicism >>>>>> is important or where performance doesn’t matter. >>>>>> >>>>>> While it would be possible to implement a JIT compiler for ObjC, I’d >>>>>> expect the wins to be low, because the “hot” code which may be hinging >>>>>> on these dynamic features is likely to already be optimized by hand. >>>>>> >>>>>> 6) GoLang: From this narrow discussion and perspective, Go has a hybrid >>>>>> model that has similar characteristics to Objective-C 2013 (which >>>>>> introduced modules, but didn’t yet have generics). It assumes static >>>>>> compilation and provides a very predictable hybrid programming model. >>>>>> Its func’s are statically dispatched, but its interfaces are dynamically >>>>>> dispatched. It doesn’t provide guaranteed dynamic dispatch (or >>>>>> “classes") like ObjC, but it provides even more dynamic feautres in >>>>>> other areas (e.g. it requires a cycle-collecting garbage collector). >>>>>> Its "interface{}” type is pretty equivalent to “id” (e.g. all uses of it >>>>>> are dynamically dispatched or must be downcasted), and it encourages use >>>>>> of it in the same places that Objective-C does. Go introduces checked >>>>>> downcasts, which introduce some run-time overhead, but also provide >>>>>> safety compared to Objective-C. Go thankfully introduces a replacement >>>>>> for the imperative constructs in C, which defines away a bunch of C >>>>>> problems that Objective-C inherited, and it certainly is prettier! >>>>>> >>>>>> … I can go on about other languages, but I have probably already gotten >>>>>> myself into enough trouble. :-) >>>>>> >>>>>> >>>>>> With this as context, lets talk about Swift: >>>>>> >>>>>> Swift is another case of a hybrid model: its semantics provide >>>>>> predictability between obviously static (structs, enums, and global >>>>>> funcs) and obviously dynamic (classes, protocols, and closures) >>>>>> constructs. A focus of Swift (like Java and Javascript) is to provide >>>>>> an apparently simple programming model. However, Swift also >>>>>> intentionally "cheats" in its global design by mixing in a few tricks to >>>>>> make the dynamic parts of the language optimizable by a static compiler >>>>>> in many common cases, without requiring profiling or other dynamic >>>>>> information.. For example, the Swift compiler can tell if methods in >>>>>> non-public classes are never overridden (and non-public is the default, >>>>>> for a lot of good reasons) - thus treating them as final. This allows >>>>>> eliminating much of the overhead of dynamic dispatch without requiring a >>>>>> JIT. Consider an “app”: because it never needs to have non-public >>>>>> classes, this is incredibly powerful - the design of the swift package >>>>>> manager extends this even further (in principle, not done yet) to >>>>>> external libraries. Further, Swift’s generics provide an a static >>>>>> performance model similar to C++ templates in release builds (though I >>>>>> agree we need to do more to really follow through on this) -- while >>>>>> Swift existentials (values of protocol type) provide a balance by giving >>>>>> a highly dynamic model. >>>>>> >>>>>> The upshot of this is that Swift isn’t squarely in either of the static >>>>>> or dynamic camps: it aims to provide a very predictable performance >>>>>> model (someone writing a bootloader or firmware can stick to using Swift >>>>>> structs and have a simple guarantee of no dynamic overhead or runtime >>>>>> dependence) while also providing an expressive and clean high level >>>>>> programming model - simplifying learning and the common case where >>>>>> programmers don’t care to count cycles. If anything, I’d say that Swift >>>>>> is an “opportunistic” language, in that it provides a very dynamic >>>>>> “default" programming model, where you don’t have to think about the >>>>>> fact that a static compiler is able to transparently provide great >>>>>> performance - without needing the overhead of a JIT. >>>>>> >>>>>> Finally, while it is possible that a JIT compiler might be interesting >>>>>> someday in the Swift space, if we do things right, it will never be >>>>>> “worth it” because programmers will have enough ability to reason about >>>>>> performance at their fingertips. This means that there should be no >>>>>> Java or Javascript-magnitude "performance delta" sitting on the table >>>>>> waiting for a JIT to scoop up. We’ll see how it works out long term, >>>>>> but I think we’re doing pretty well so far. >>>>>> >>>>>> TL;DR: What I’m really getting at is that the old static vs dynamic >>>>>> trope is at the very least only half of the story. You really need to >>>>>> include the compilation model and thus the resultant programmer model >>>>>> into the story, and the programmer model is what really matters, IMHO. >>>>>> >>>>>> -Chris >>>>> >>>>> _______________________________________________ >>>>> swift-evolution mailing list >>>>> [email protected] >>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>> >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> [email protected] >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] >>> https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
