> 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.

> 
> Brandon 
> 
> On May 20, 2016, at 12:21 PM, Matthew Johnson via swift-evolution 
> <[email protected] <mailto:[email protected]>> wrote:
> 
>> 
>>> On May 20, 2016, at 11:17 AM, Austin Zheng via swift-evolution 
>>> <[email protected] <mailto:[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] <mailto:[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/
>>>>  
>>>> <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 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>> 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 
>>>>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>> 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] <mailto:[email protected]>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to