I definitely prefer static typing over dynamic typing. I don't really mind duck typing so much as I mind dynamic duck typing (for example I like how Go does duck typing).
I do try to mention that preference for static typing in the post a few times, to make it clearer that it's the dynamism that's bothering me (as opposed to the design being wrong).
Discussions about typing seem pretty fruitless because there are often a lot of people talking past each other because they're not working off of shared definitions of what the terms (typed untyped static dynamic strong weak) actually mean.
But you're dead on about strong/weak. You may get away with stronger and weaker, but strong and weak have no widely agreed upon meaning w.r.t. types.
Unfortunately in iOS development, we don't have a good alternative to ObjC.
`[nil methodname]` returns nil. Python et al have the decency to crash to the ground, look embarassed, and stop running.
In any of those, dereferencing a null pointer is undefined. The compiler can literally emit code that plays Nethack in this situation [0]. ObjC's "nothing will happen" behavior is a significant improvement in safety against similarly-situated languages.
I'm pretty sure I'm on record in HN for ranting about the fact that C & C++'s undefined & funny behavior literally created multimillion dollar industries in building analysis tools to cove their gaping problems. Which is why I am tend to boost Rust when possible (designed for correctness and determinism! woo!).
Dropping errors is not IMO better or worse. Both are silent failure modes.
NSArray *a = [self somethingThatProducesAnArray];
if (a.count > 0) {
// do something
}
else {
// do something else
}
than NSArray *a = [self somethingThatProducesAnArray];
if (a && a.count > 0) {
// do something
}
else {
// do something else
}Again, message, not method.
For extra fun, NSNull (the "designated" object (as opposed to an actual zero value of nil) to represent nil) doesn't happily respond to any message sent to it -- i.e., if you replace nil with NSNull somewhere in the code, it will most likely blow up.
It is a duck-typed language. This is the philosophy that "if it walks like a duck... it's a duck." This is the philosophy used by lots of modern languages like Python, Ruby, and JS.
Meanwhile there is the statically-typed system, which wants you to declare things to be ducks explicitly (or to pick up a duck declaration through an inheritance system). This is the philosophy used by Java, C++, etc.
Anyway, the author's gripe isn't with ObjC's types. The author's gripe is with any duck-typed system. The whole point of these type systems is to avoid providing any strong guarantees about types. If you want strong typing, use a strongly-typed language. C++ may align better with this author's programming ideology.
It's also worth pointing out that runtime type checks are, all else being equal, slow. ObjC is used primarily in mobile environments where speed is a concern. As the author discovered, you can opt in to type checking by using NSAssert. This forces you to think about whether the cost of a dynamic type check is acceptable. NSAsserts are also disabled by default in release builds, so this gives you checking when you need them (development) and speed when you don't (production).
C++'s type system is deliberately constructed in such a way that the compiler can do the bulk of the type enforcement, which is much faster than runtime type checking. Alternately stated, this means that the programmer must write code in such a way that the compiler can infer/enforce type checks, or else they will get type errors. The author's complaints about not enough compiler errors seem to suggest to me that he would be more at home in a language like C++ that is specifically designed for this purpose.