+1 to the concerns voiced by Doug, Matthew and others. I , too, would prefer a 
generator which generates a statically typed bridge instead of the dynamic 
lookup ature proposed which effectively undermines Swift's static type system.


> Am 30.11.2017 um 15:15 schrieb Matthew Johnson via swift-evolution 
> <swift-evolution@swift.org>:
> Sent from my iPad
>> On Nov 30, 2017, at 2:24 AM, Douglas Gregor via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>>> On Nov 26, 2017, at 10:04 PM, Chris Lattner via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> I’d like to formally propose the inclusion of user-defined dynamic member 
>>> lookup types.
>>> Here is my latest draft of the proposal:
>>> https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438
>>> https://github.com/apple/swift-evolution/pull/768
>>> An implementation of this design is available here:
>>> https://github.com/apple/swift/pull/13076
>>> The implementation is straight-forward and (IMO) non-invasive in the 
>>> compiler.
>> I think better interoperability with Python (and other OO languages in 
>> widespread use) is a good goal, and I agree that the implementation of the 
>> feature described is straight-forward and not terribly invasive in the 
>> compiler.
>> However, I do not think this proposal is going in the right direction for 
>> Swift. I have objections on several different grounds.
> +1 to everything Doug says here.  He articulates the concerns I tried to 
> voice in an earlier thread more clearly and more thoroughly.  
> This design introduces a significant hole in the type system which is 
> contrary to the spirit of Swift.  It doesn’t just make dynamic language 
> interop easy, it also changes the semantics of any type which conforms to 
> DynamicMemberLookupProtocol.  That is not something that is locally visible 
> when looking at a piece of code.  Worse, it does so in a way that trivial 
> mistakes such as a typo can turn into runtime errors.  Worst of all, as Doug 
> points out it is possible to use retroactive conformance to change the 
> semantics of vast quantities of widely used types in one fell swoop.
> One additional concern that I don’t believe has been mentioned is that of 
> evolution.  When a library is imported from a dynamic language and the 
> library makes breaking changes Swift code written using this feature will 
> break without notice until a runtime error occurs.  Is that acceptable?  That 
> may be what users of dynamic languages are accustomed to but can we do better 
> in Swift?  If we can make the process of upgrading dependencies less a less 
> harrowing experience perhaps that could be a major selling point in moving 
> them to Swift.  But we won’t accomplish that with this design.
> Interop with dynamic languages is a worthy goal, but we should do it in a way 
> that has no potential impact on code that does not need the feature.  A 
> semantic variant of “don’t pay for what you don’t use” should apply here.  If 
> we add this feature everyone will pay for it every time they read unfamiliar 
> Swift code.  They will have to contend with the potential for conformances to 
> this protocol, even on standard library types.  That feels like a pretty high 
> cost to me, especially for programmers who aren’t using the dynamic language 
> interop features themselves.
> Further, a consistent theme has been the desire to avoid things like compiler 
> flags that could fragment the community.  I fear this feature has the 
> potential to do that, especially if it is really successful at attracting 
> people from the dynamic language community.  I think we should consider 
> carefully the following questions:
> * Do we want to encourage these programmers to continue writing code in an 
> extremely dynamic style when they come to Swift or do we want to encourage 
> them to embrace the advantages of relying on the type system?  
> * If we want them to embrace the type system but that would keep them away 
> from Swift how do we feel about that?  
> Matthew
>> Philosophy
>> Swift is, unabashedly, a strong statically-typed language. We don’t allow 
>> implicit down casting, we require “as?” so you have to cope with the 
>> possibility of failure (or use “as!” and think hard about the “!”). Even the 
>> gaping hole that is AnyObject dispatch still requires the existence of an 
>> @objc declaration and produces an optional lookup result, so the user must 
>> contend with the potential for dynamic failure. Whenever we discuss adding 
>> more dynamic features to Swift, there’s a strong focus on maintaining that 
>> strong static type system.
>> IMO, this proposal is a significant departure from the fundamental character 
>> of Swift, because it allows access to possibly-nonexistent members (as well 
>> as calls with incorrect arguments, in the related proposal) without any 
>> indication that the operation might fail. It’s easy to fall through these 
>> cracks for any type that supports DynamicMemberLookupProtocol—a 
>> single-character typo when using a DynamicMemberLookupProtocol-capable type 
>> means you’ve fallen out of the safety that Swift provides. I think that’s a 
>> poor experience for the Python interoperability case, but more on that in 
>> the Tooling section below.
>> While we shouldn’t necessarily avoid a feature simply because it can be used 
>> distastefully, consider something like this:
>>      public extension NSObject :  DynamicMemberLookupProtocol, 
>> DynamicCallableProtocol { … }
>> that goes directly to the Objective-C runtime to resolve member lookups and 
>> calls—avoiding @objc, bridging headers, and so on. It’s almost frighteningly 
>> convenient, and one could imagine some mixed Objective-C/Swift code bases 
>> where this would save a lot of typing (of code)… at the cost of losing 
>> static typing in the language. The presence of that one extension means I 
>> can no longer rely on the safety guarantees Swift normally provides, for any 
>> project that imports that extension and uses a subclass of NSObject. At 
>> best, we as a community decide “don’t do that”; at worse, some nontrivial 
>> fraction of the community decides that the benefits outweigh the costs (for 
>> this type or some other), and we can no longer say that Swift is a strong 
>> statically-typed language without adding “unless you’re using something that 
>> adopts DynamicMemberLookupProtocol”.
>> Tooling
>> The Python interoperability enabled by this proposal *does* look fairly nice 
>> when you look at a small, correctly-written example. However, absolutely 
>> none of the tooling assistance we rely on when writing such code will work 
>> for Python interoperability. Examples:
>> * As noted earlier, if you typo’d a name of a Python entity or passed the 
>> wrong number of arguments to it, the compiler will not tell you: it’ll be a 
>> runtime failure in the Python interpreter. I guess that’s what you’d get if 
>> you were writing the code in Python, but Swift is supposed to be *better* 
>> than Python if we’re to convince a community to use Swift instead.
>> * Code completion won’t work, because Swift has no visibility into 
>> declarations written in Python
>> * Indexing/jump-to-definition/lookup documentation/generated interface won’t 
>> ever work. None of the IDE features supported by SourceKit will work, which 
>> will be a significant regression for users coming from a Python-capable IDE.
>> Statically-typed languages should be a boon for tooling, but if a user 
>> coming from Python to Swift *because* it’s supposed to be a better 
>> development experience actually sees a significantly worse development 
>> experience, we’re not going to win them over. It’ll just feel inconsistent.
>> Dynamic Typing Features
>> It’s possible that the right evolutionary path for Swift involves some 
>> notion of dynamic typing, which would have a lot of the properties sought by 
>> this proposal (and the DynamicCallableProtocol one). If that is true—and I’m 
>> not at all convinced that it is—we shouldn’t accidentally fall into a 
>> suboptimal design by taking small, easy, steps. If we’re to include 
>> dynamic-typing facilities, we should look at more existing practice—C# 
>> ‘dynamic' is one such approach, but more promising would be some form of 
>> gradual typing a la TypeScript that let’s one more smoothly (and probably 
>> explicitly) shift between strong and weak typing.
>> How Should Python Interoperability Work?
>> Going back to the central motivator for this proposal, I think that 
>> providing something akin to the Clang Importer provides the best 
>> interoperability experience: it would turn Python declarations into *real* 
>> Swift declarations, so that we get the various tooling benefits of having a 
>> strong statically-typed language. Sure, the argument types will all by 
>> PyObject or PyVal, but the names are there for code completion (and 
>> indexing, etc.) to work, and one could certainly imagine growing the 
>> importer to support Python’s typing annotations. But the important part here 
>> is that it doesn’t change the language model at all—it’s a compiler feature, 
>> separate from the language. Yes, the Clang importer is a big gnarly 
>> beast—but if the goal is to support N such importers, we can refactor and 
>> share common infrastructure to make them similar, perhaps introducing some 
>> kind of type provider infrastructure to allow one to write new importers as 
>> Swift modules.
>> In truth, you don’t even need the compiler to be involved. The dynamic 
>> “subscript” operation could be implemented in a Swift library, and one could 
>> write a Python program to process a Python module and emit Swift wrappers 
>> that call into that subscript operation. You’ll get all of the tooling 
>> benefits with no compiler changes, and can tweak the wrapper generation 
>> however much you want, using typing annotations or other Python-specific 
>> information to create better wrappers over time.
>>      - Doug
>> _______________________________________________
>> 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
swift-evolution mailing list

Reply via email to