On 2016-07-19 11:35:03 +0000, Brent Royal-Gordon via swift-evolution said:


On Jul 19, 2016, at 4:00 AM, Károly Lőrentey via swift-evolution <swift-evolution@swift.org> wrote:

"dynamic final" is prohibited by the current version of compiler.

Huh, I didn't know that. I don't agree with that design.

(However, I do notice that a `final` class can have `dynamic` members.)

I'm very very far from understanding how Swift interacts with the Obj-C runtime, but I believe that might be a bug. I do not expect e.g. KVO to work correctly on these. I don't think the Objective-C runtime understands or enforces final (at neither class nor member level), and I expect abusing it to break out of "final" (at either level) could violate critical compile-time assumptions and cause deep problems. I think this also applies to anything with @objc that isn't also declared dynamic -- even "@objc open" members aren't necessarily dispatched via message passing, are they?

Can you provide an example of a problem that would be solved by allowing it?

In our current Objective-C world, the obvious example would be an NSObject subclass with a property that should not be overridden (so you want to mark it `final`), but which participates in KVO (so in fact Foundation will use the Objective-C runtime to invisibly subclass the class, override the setter, and change the type of the instance to the subclass). I believe it makes perfect sense to declare such a property `dynamic final`; the Objective-C-level overriding performed by Foundation is an implementation detail, and does not change the fact that you should never declare an override of that property.

To me, it doesn't make much sense to declare that a property must not be overridden, then expect KVO to be able to override it anyway. "dynamic" clearly does allow overriding (and more); it just adds supports for a less convenient syntax. AFAIK KVO isn't using secret APIs that aren't also available to my API clients. If I choose to use "dynamic" in my API, then I have to design for whatever the Objective-C runtime supports, and that includes overrides. Only disallowing overrides with Swift syntax doesn't seem to be much of a win here.

I'm not saying we couldn't come up with some coherent definition for a hypothetical "final dynamic"; I just really don't see what would be the point of it, besides making the language more complicated.

It's not really clear how `dynamic` would be used without Objective-C, but I could imagine analogous situations, like an ORM implementing Core Data-style faults using dirty, low-level class-changing hacks. A class that was *semantically* `final`, and thus ought to be eligible for static dispatch, might thus require dynamic dispatch anyway.

It is nice (and critically important) that we can keep using Cocoa in Swift; but supposing we wanted to create a brand new ORM for a hypothetical "Swifty Cocoa", it wouldn't make much sense to do it using the same runtime techniques as Core Data. (After all, we already have such a framework in Swift; it's called Core Data.) I'd prefer to choose a swiftier approach, like generating the equivalent of NSManagedObject's model-specific boilerplate at compile time.

<off-topic>
Cocoa currently hides the boilerplate for all of these wonderful constructs behind amazingly effective runtime acrobatics. This fits perfectly into Objective-C, and it also works very well in Swift. But such features could be in better harmony with Swift's unique set of language constructs if their boilerplate was hidden behind amazingly effective **compile-time** acrobatics instead.

Such compile-time acrobatics are hard to perform today, and it is possible that the ability to create such systems will forever remain an advanced skill, just like forging runtime magic requires advanced skills in Objective-C.

But Swift doesn't have an analogue to objc/runtime.h yet. What will such a thing look like? A general metaprogramming/DSL subsystem (like some form of hygienic macro engine)? A family of narrowly scoped language/compiler features that provide extensible syntactic sugar to get rid of specific kinds of boilerplate (like property behaviors or coroutines)? A set of standalone tools for generating Swift source code (like mogenerator)? Something else? Some combination of these?

I'd like to move on from the Objective-C runtime and start exploring this rich new frontier; I think it's awesome that Swift isn't *just* a bracket-free dialect of Objective-C.

I'm sorry for derailing the discussion. I think we agree on most of this, anyway.
</off-topic>

--
Károly
@lorentey


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to