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

Reply via email to