4 ms·
Sorry but final by default is not a good idea IMO. All my work is client work. There have been a bunch of occasions where I've had to work around some weirdnes
by allsystemsgo 10y ago
Sorry but final by default is not a good idea IMO.
All my work is client work. There have been a bunch of occasions where I've had to work around some weirdness of an Apple SDK by creating my own subclass. I could see Apple releasing an SDK and many of the classes being @final. Then I'm stuck in a situation where I can't provide a deliverable to the specifications a client wants due to a limitation in an SDK.
That's my only fear though really. Rarely do I personally do a lot of subclassing unless I absolutely have to or it really does make sense to.
- shawkinaw 10y agoAgreed. I don't even like the fact that you can turn off subclassing, that's very un-object-oriented IMHO.
- chris_7 10y agoIdiomatic Swift is primarily protocol-based, object-orientation is mostly used when talking to the Cocoa frameworks, which aren't idiomatic Swift code. But the main problem with subclassing is: https://en.wikipedia.org/wiki/Fragile_base_class https://en.wikipedia.org/wiki/Fragile_base_class
- stcredzero 10y agoBack in the day, with Smalltalk, a programmer could override everything. If you did something that broke derived classes, you were simply being a bad programmer. You simply didn't do that, and if you couldn't deduce if your change would do this or not, you either had a badly architected system, or you were being a bad programmer. This is how it should work in many production environments: Are you 100% sure about that? No? Don't do that! Then start asking why you can't be sure, then fix that. Rinse, repeat.
- chris_7 10y ago"final" allows the compiler to strictly enforce that "don't break things" idea, instead of delegating it to fallible humans. (it also lets the compiler make your code faster) By using the tools that Swift provides - preferring value types, and falling back on final classes, I can much more easily deduce what my changes will do. Non-final classes create an additional public API that framework authors need to support - the ability to change any behavior. Reducing the surface for potential errors makes frameworks and their clients more robust.
- stcredzero 10y agoBy using the tools that Swift provides - preferring value types, and falling back on final classes, I can much more easily deduce what my changes will do. No disagreement here. Non-final classes create an additional public API that framework authors need to support - the ability to change any behavior. Reducing the surface for potential errors makes frameworks and their clients more robust. Since Smalltalkers knew all their code was "surface," there was motivation to keep things very encapsulated. (Perhaps this is part of why the Law of Demeter was so big in that programming culture.) Synergistic with this, was the heavy use of the very powerful debugger. If your codebase was mostly relatively stateless or very well encapsulated, you could time-travel with ease in the debugger by unwinding the stack, recompile your method in place, and continue on. Conversely, if you wrote code that didn't have those qualities, your fellow programmers would get annoyed at you for making their lives harder and their tools much harder to use. Increasing the surface makes frameworks more flexible and necessitates good design throughout. Is there a trade-off? Sure. The really good Smalltalkers spent lots of time reading code and exploring stuff in the debugger/browsers. And sometimes, you could be stymied because you couldn't rule out stuff and risk a blow-up in production. And to be fair, in my estimation, Smalltalk projects were less robust -- but got fixed really quickly. Nowadays, I think the sweet spot would be in a simple language with super fast compile/edit/test cycles, with equally powerful debugging, and with type annotations.
- panic 10y agoObjective-C (and Swift) don't have the fragile base class problem: http://www.sealiesoftware.com/blog/archive/2009/01/27/objc_explain_Non-fragile_ivars.html http://www.sealiesoftware.com/blog/archive/2009/01/27/objc_e...
- chris_7 10y agoThey don't have it for ivars, but that's just one potential problem.
- StevePerkins 10y agoI don't have any experience with Swift, but how to you approach unit testing with everything `final`? Being able to inject mock subclasses is a staple of OO testing.
- solipsism 10y agoI don't know Swift, but I know I testing... your constructors should be accepting interfaces (for things that are complex enough that you'd want to mock them), not concrete types. In Swift I gather you'd use protocols.
- StevePerkins 10y agoShrug... at least in the Java world, modern mocking frameworks render obsolete the J2EE-era "interfaces for the sake of interfaces" boilerplate. On the other hand, none of them work if the class you're mocking is `final`.
- chris_7 10y agoProtocols and generics cover everything you need to do that. Idiomatic Swift makes little use of classes to begin with, it's mostly structs, enums, and protocols, none of which allow inheritance.
- chris_7 10y agoApple's ability to release a Swift-based SDK that uses "final" and "final" being the default for classes in Swift are completely orthogonal concepts. Apple could (and should, I think) release future SDKs that use all-final classes and require composition instead of the incredibly fragile base classes that currently make up UIKit and Foundation - they'd just add the "final" keyword. Since UIKit is inheritance-based currently, in a final-by-default Swift, it would be imported as "subclassable", "nonfinal", or whatever. Nothing would change other than the default for newly-written Swift code.
- geofft 10y agoIt would be nice to have an "evil_override" keyword (or some other such name). There's no fundamental technical reason you can't do it, with unsafe pointer black magic if necessary, and it's sort of like an LD_PRELOAD: it's not a good solution, but sometimes you have to break abstraction barriers to get things done, and at least if you're using it you're explicitly saying you're breaking abstraction barriers. final by default doesn't prevent someone from manually adding final to their classes.
- mikeash 10y agoThat wouldn't really work, because the compiler can do things like generate static dispatch or even inline method calls for final classes.