>From the compilers/runtimes perspective why couldn't the declaration 
>automatically be included in the main protocol definition as if it was defined 
>there?

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

Reply via email to