I've had a chance to work on a fairly large chunk of Python at this point and have decided that Python (like Perl) is completely untenable at scale. <rant><rave><drool> but wait! I have reasons!
Programmers spend most of their time reading code. We read massive amounts of code. After we read massive amounts of code we write one... or change one... To make a change to a piece of code you first have to understand what it does and how it interacts with the system around it. Then we start reading massive amounts of code again. Anything you can do to minimize the amount of code a programmer has to understand to make a change becomes a huge gain in productivity.
Duck typing causes the amount of code you need to read to make a change to grow very large.
For example lets look at two functions, one in C++ and one in Python.
First in C++
int function(type1 arg1, type2 arg2) {
return arg1->method(arg2);
}
In this function we know that it takes two types, type1 and type2. We also know that type1 has a function called 'method' which takes an argument of type2. If we need to understand this function we go to type1 and read the code. If 'method' is virtual then we also read any class which inherits from type1. Now lets look at an equivalent Python function.
Now in Python
def function(arg1, arg2):
return arg1.method(arg2)
In this case the function takes any class which has a function called 'method'. To understand this function you have to read the entire codebase to find classes which have a 'method' function or find every invocation of this function and determine the types used there (non trivial). Even worse a class might not have 'method' but could gain it later. To understand this function you really have to read everything.
This isn't a problem when dealing with hundreds of lines of code but when dealing with tens of thousands it becomes extremely time consuming.
Programmers spend most of their time reading code. We read massive amounts of code. After we read massive amounts of code we write one... or change one... To make a change to a piece of code you first have to understand what it does and how it interacts with the system around it. Then we start reading massive amounts of code again. Anything you can do to minimize the amount of code a programmer has to understand to make a change becomes a huge gain in productivity.
Duck typing causes the amount of code you need to read to make a change to grow very large.
For example lets look at two functions, one in C++ and one in Python.
First in C++
int function(type1 arg1, type2 arg2) {
return arg1->method(arg2);
}
In this function we know that it takes two types, type1 and type2. We also know that type1 has a function called 'method' which takes an argument of type2. If we need to understand this function we go to type1 and read the code. If 'method' is virtual then we also read any class which inherits from type1. Now lets look at an equivalent Python function.
Now in Python
def function(arg1, arg2):
return arg1.method(arg2)
In this case the function takes any class which has a function called 'method'. To understand this function you have to read the entire codebase to find classes which have a 'method' function or find every invocation of this function and determine the types used there (non trivial). Even worse a class might not have 'method' but could gain it later. To understand this function you really have to read everything.
This isn't a problem when dealing with hundreds of lines of code but when dealing with tens of thousands it becomes extremely time consuming.
Completely agree with you. We have a large codebase dating back to 2013 and it's getting to be nearly impossible to know where things will be coming from when we call them.
ReplyDelete