Short answer: no, because Turing equivalence.
Long answer: This guy's being a troll. While it's true that type systems "restrict you to a subset," the stuff outside that subset is, by definition, stuff that does not work.
Anything you're able to do in any Turing-complete programming language (which is language designed for general-purpose programming, plus plenty that aren't; it's a pretty low bar to clear and there are several examples of a system becoming Turing-complete unintentionally) you are able to do in any other Turing-complete programming language. This is called "Turing equivalence," and it only means exactly what it says. Importantly, it does not mean that you can do the other thing just as easily in the other language--some would argue that that's the entire point of creating a new programming language in the first place: to give you a better way of doing certain things that existing languages suck at.
A dynamic type system, for example, can be emulated on top of a static OO type system by just declaring all variables, parameters, and return values as the base Object
type and then using reflection to access the specific data within, so when you realize this you see that there's literally nothing you can do in a dynamic language that you can't do in a static language. But doing it that way would be a huge mess, of course.
The guy from the quote is correct that static types restrict what you can do, but that's an important feature, not a problem. The lines on the road restrict what you can do in your car, but do you find them restrictive, or helpful? (I know I wouldn't want to drive on a busy, complex road where there's nothing telling the cars going the opposite direction to keep to their side and not come over where I'm driving!) By setting up rules that clearly delineate what's considered invalid behavior and ensuring that it won't happen, you greatly decrease the chances of a nasty crash occurring.
Also, he's mischaracterizing the other side. It's not that "all the interesting programs you want to write will work as types", but rather "all the interesting programs you want to write will require types." Once you get beyond a certain level of complexity, it becomes very difficult to maintain the codebase without a type system to keep you in line, for two reasons.
First, because code with no type annotations is hard to read. Consider the following Python:
def sendData(self, value):
self.connection.send(serialize(value.someProperty))
What do you expect the data to look like that the system at the other end of the connection receives? And if it's receiving something that looks completely wrong, how do you figure out what's going on?
It all depends on the structure of value.someProperty
. But what does it look like? Good question! What's calling sendData()
? What is it passing? What does that variable look like? Where did it come from? If it's not local, you have to trace through the entire history of value
to track down what's going on. Maybe you're passing something else that also has a someProperty
property, but it doesn't do what you think it does?
Now let's look at it with type annotations, as you might see in the Boo language, which uses very similar syntax but is statically typed:
def SendData(value as MyDataType):
self.Connection.Send(Serialize(value.SomeProperty))
If there's something going wrong, suddenly your job of debugging just got an order of magnitude easier: look up the definition of MyDataType
! Plus, the chance of getting bad behavior because you passed some incompatible type that also has a property with the same name suddenly goes to zero, because the type system won't let you make that mistake.
The second reason builds on the first: in a large and complex project, you've most likely got multiple contributors. (And if not, you're building it yourself over a long time, which is essentially the same thing. Try reading code you wrote 3 years ago if you don't believe me!) This means that you don't know what was going through the head of the person who wrote almost any given part of the code at the time they wrote it, because you weren't there, or don't remember if it was your own code a long time ago. Having type declarations really helps you understand what the intention of the code was!
People like the guy in the quote frequently mischaracterize the benefits of static typing as being about "helping the compiler" or "all about efficiency" in a world where nearly unlimited hardware resources make that less and less relevant with each passing year. But as I've shown, while those benefits certainly do exist, the primary benefit is in the human factors, particularly code readability and maintainability. (The added efficiency is certainly a nice bonus, though!)