Types and Schemas
Some arguments offered for no types in a programming language are that types make a programming language too cumbersome or verbose, and the code less readable.
Those arguments are kind of similar to those proferred during the height of NoSQL hype. But now that the hype has died, we know that schema for data is good. Data lives on for decades and it is better that as much of the schema as possible lives close to the data, like in a RDBMS, as opposed to far away from data in a NoSQL application where most of the schema lives in code.
A reasonably designed RDBMS is much easier to understand 10 years down the line than an application where schema is in the code.
Types in programming language also provide a schema of sorts for the data that the code acts on. The more information about that schema we can encode in inputs and outputs of functions, the more maintainable the code becomes. Any competent IDE will allow you to step through code without running it, and without sprinkling print statements everywhere.
I came across this article "Strong Typing vs. Strong Testing" while reading the book Fluent Python. In it, an example was given to justify why loose typing is better.
The example:
# Speaking pets in Python, but without base classes:
class Cat:
def speak(self):
print "meow!"
class Dog:
def speak(self):
print "woof!"
class Bob:
def bow(self):
print "thank you, thank you!"
def speak(self):
print "hello, welcome to the neighborhood!"
def drive(self):
print "beep, beep!"
def command(pet):
pet.speak()
pets = [ Cat(), Dog(), Bob() ]
for pet in pets:
command(pet)
The conclusion by the article:
Since command(pet) only cares that it can send the speak() message to its argument, I've removed the base class Pet, and even added a totally non-pet class called Bob which happens to have a speak() method, so it also works in the command(pet) function.
At this point, a strong, statically-typed language would be sputtering with rage, insisting that this kind of sloppiness will cause disaster and mayhem. Clearly, at some point the "wrong" type will be used with command() or will otherwise slip through the system. The benefit of simpler, clearer expression of concepts is simply not worth the danger. Even if that benefit is a productivity increase of 5 to 10 times over that of Java or C++.
For me, this illustrates the fundamental problem with loose typing. Given a class Bob, how do I know who all are calling the speak method? In a statically typed language, this is trivial. An IDE can get you all the references with a single keyboard shortcut. In a loosely typed language, you either need to spend a lot of time analyzing the code, and/or add a bunch of print statements to determine who is calling a function.
Code is read more than is written, and by people who did not write the code. While loose typing can seem clearer to the person writing the code, it is anything but for the poor sod who has to fix a pressing bug yesterday. Even if you are the only person who is going to read what you wrote, the code will not be clearer when you come back to it in a year and when the schema of the code that lived in your brain is clean gone.