Apple Should've Enhanced Objective-C Instead of Building Swift
Apple moved from Objective-C to Swift some years back.
I think this is a mistake: it imposed costs disproportionate to the benefits.
Instead of throwing away Objective-C, Apple should’ve evolved it to fix specific and known problems, while not fixing what’s not broken.
Why do I believe this?
First, Objective-C is already a powerful language with a lot features like blocks, extensions to add functions to an already existing class, properties (syntactic sugar for getters and setters), exceptions, keyword arguments, and so on. If Apple were stuck with a primitive language like C, there would have been a stronger case for Swift.
Second, when you throw something away and design something new, you may think it’s unequivocally better, but others often will point out the downsides you’ve missed. It amounts to taking some steps forward and some steps back. For example, Swift’s overly strict type checking made my app crash at runtime, which wouldn’t have happened in Objective-C. As a second example, Objective-C classes separate implementation from interface in different files, make it more readable for people who just want to use the class without needing to know its internals. This is one of the fundamental principles of software engineering, and Swift regresses here. So, when you design a new language, it will be worse in some ways.
Third, some of the problems with the older language are not solved with the newer one, either. An example is initialisers, known as constructors in other languages. When I subclass, Swift sometimes gives me an error saying that I need to implement an initialiser from the subclass. Xcode offers to autogenerate this, and if I ask it to, it generates an implementation that fails at runtime. Runtime failure is bad, and this is a problem Objective-C had, too. Other languages like Java don’t have this problem, since constructors in Java aren’t inherited: when you define a subclass in Java, you define whatever constructors make sense for the subclass, without being forced to implement constructors that make no sense and can only fail at runtime. So, if Swift doesn’t solve a problem Objective-C has, that waters down the case for Swift.
Fourth, Swift is a very complex language, more than Objective-C. People new to the Apple ecosystem have a steeper learning curve than they’d have if Apple stuck with Objective-C. Even experienced Objective-C engineers have had to go through a long retraining period. It took me some 6 months before I was writing idiomatic Swift code. That was certainly not worth it — it did not give me results commensurate with such a long learning curve. I’m not interested in running to stay still. It doesn’t generate business value, and wastes my time. I could have spent that time learning something more useful like FaaS. Even once engineers have learnt Swift, there’s the cost of migrating Objective-C code that Apple foisted on all companies in the ecosystem.
Fifth, many companies have complex Objective-C codebases that won’t disappear for years. So they have to deal with the added complexity of two languages.
The other option would have been to evolve Objective-C. Add features like type inference. For example, C++ does type inference this way:
auto height = 20;
Objective-C could have copied this auto keyword.
Swift has excellent control flow features in the form of guard and defer, which could have been added to Objective-C.
Likewise for string interpolation, which may seem like a small feature but reduces a common annoyance.
Another downside of Objective-C is that it’s more verbose. Instantiation requires
[[MyClass alloc] initWithBlah: blah]
as compared to
MyClass(blah: blah)
in Swift. Again, syntactic sugar could have been added for this case, like the := operator in Go.
Objective-C is a superset of C, and inherits some mis-features of C. For example, there’s no bounds-checking. But that can be fixed by throwing an exception when accessing beyond the bounds of an array, which would still comply with the C spec 1.
All these improvements could have been made to Objective-C, at less disruption to the ecosystem than defining Swift. Defining a new language is a lot of fun, and it can often be the idealistic choice, but it's often not the pragmatic one, just as saying “My text editor has some problems, so let me build a new one!” is not the sensible choice.
Indexing beyond the bounds of an array is undefined in C, which means anything can happen, and an exception counts as “anything”.
An unsafe_index intrinsic could be added to index into an array without bounds checking for those 1% of times when the performance difference matters, while ensuring most code is safe. Security should be the default.