Friday, November 25, 2016

Response to Apple: The Good, the Bad, and the Ugly

This started life as a comment on Steve Yegge's The Monkey and the Apple post.

In the section Apple: The Good, the Bad, and the Ugly, Steve said:
[Objective-C] has generics, literal syntax for sets/dictionaries/arrays, try/catch/finally macros, extremely well-implemented lambdas with proper closure capturing (unlike nearly every other non-functional language out there), properties, and many other modern conveniences.

[Objective-C] Has Generics

Objective-C's generics are extremely weak. You can only define a generic type with a class method, so you can't have per-method types like in Java. Also, Objective-C classes aren't generic, so generic type-safe casting isn't possible.

Literal Syntax For Sets/Dictionaries/Arrays

Literal sets/dictionaries/arrays aren't generic, so you must use old-fashioned mutable collections if you want generic safety.

try/catch/finally macros

You're never supposed to use exceptions for control flow. Exceptions are only for programmer error, and are almost always supposed to cause a crash. Thus, the @try/@catch/@finally macros are useless.

Extremely Well-Implemented Lambdas with Proper Closure Capturing

Objective-C lambdas (blocks) are the one bright spot of the language, excepting that they don't work properly with generics.

Missing Features

Steve left out nullability from the language feature list. It works somewhat, but I haven't had enough time yet to do a proper analysis. The nullability syntax is overly complex, however. There are 3 different ways to declare nullability.

Downsides of Swift

Later, Steve says:
Obviously today I'd do it in Swift
This seems obvious, but Swift has a few major downsides that could be deal-breakers.
  • Some people report inability to print variables from LLDB for the past 2 years
  • Swift only supports modularity with dynamic libraries. If you use too many dynamic libraries, your app will start slowly. Objective-C still supports static linking, so you can use as many libraries as you want without affecting startup time.
  • The Swift runtime adds 18 MB to your app's binary size. Apple will probably strip unneeded binaries from the runtime when individual users install, but if 32-bit ARM and 64-bit ARM both have the same-sized binary, the Swift runtime adds 9MB at install-time.