Thank you. Also, I think we need a simple theorem that works with what average programmers understand easily. This is why I called it the Common Fundamental Theorem.
"Given any two unobfuscated source codes, the one that produces more value in average per line of code is greater."
For some software, higher performance is more valuable than fewer lines of code. For example, if you re-wrote the Linux kernel in Lisp, it might have many fewer lines of code than the current C version, but would deliver less value because it would run much slower and might stop for garbage collection in the middle of an interrupt handler. Concerns about real-time performance and memory-usage would also apply to lots of embedded software, like the code that controls the engine in your car.
I'm not sure that I'd call something a "fundamental theorem of software development" if there are large classes of software that it doesn't apply to.
For some software, higher performance is more valuable than fewer lines of code.
I suggest you re-read the lemma. The point is about having fewer lines of code for what the program is supposed to do. For example, one could probably not write a kernel that does exactly what the linux kernel does (that has the exact same behavior [1]) but with dramatically less lines of code.
[1] the performances of the linux kernel are part of what that program does
I think your conclusion might be vacuous, or at least oversimplified. What is "value"? If we don't assume that it takes a programmer a set amount of time to write any line of code (and I know it takes me much longer to do linear algebra in Haskell than bung out a bunch of arithmetic in Python), any manager would be just as happy with B. B might even be more maintainable- it might be so long because its done in Knuthian-style literate programming, say- or have other virtues above A, increasing its "value," by most peoples' estimation.
What in particular do you mean when you say A is "greater"?
Greater means anything that you can think of that would be greater for a program. For example, it would be faster. It would be more maintainable. It would be more everything.
We ultimately don't have to prove it. We only have to agree together. (Another way of saying this is that it's unprovable, but every programming master will tell you it's true)
There's definitely some linear algebra which should be happening in the head of any programmer as s/he writes code, some combination and balance of functionality, conciseness, performance, readability / maintainability, extensibility, etc.
I'd suggest that this lemma doesn't quite take into account that software quality isn't just about what it is able to do today, but how efficiently it's able to adapt or be repaired in the future.
This sounds like a load of pseudo-mathematical bullshit to me.
I agree with the principle behind it, which I believe to be "all else being equal, fewer lines of code is better than more lines of code," but I'd argue that all else is rarely equal. Sometimes, spelling things out in a slightly more verbose way is better than using some slick one-liner.
When I was in grad school, I was that guy who would strive to get his proofs as short as possible, but no shorter. Since my audience consisted of fellow students (who could be expected to be at least as capable as me), and PhD mathematicians, a short, clever proof had much higher value than a long, plodding argument. (But, even the short proof needed to be understandable: I recall reading a paper co-authored by several famous mathematicians that included a diagram to show the structure of the proof, not the mathematical objects that were the subject of the proof!)
Software is not mathematics and it shouldn't be treated as such. Remember that code is read many more times than it is written; and that the audience is the people who will come behind you and read the code, not the compiler.
> Sometimes, spelling things out in a slightly more verbose way is better than using some slick one-liner.
I think you may have missed some details here. First, the code must be non-obfuscated. Here is the trick: you decide actually when the code is obfuscated. When it is, you probably want a more verbose code indeed.
You understand that, at some point in time, it may be hard for a programmer, you, to judge if your code is obfuscated or if it is actually weak code. If other programmers feel fine with the slick one-liner, the theorem would suggest that it might be useful for you to learn to read easily that kind of code because you may be actually writing weak code.
Finally on this: local exceptions are ok. It's all about averages.
> "all else being equal, fewer lines of code is better than more lines of code," but I'd argue that all else is rarely equal
I believe you make a little mistake here. It not all else being equal. It's for a program that does x. For a program that does x, fewer lines of code is better. Please note that, "does x" includes the complete behaviour of the program, performances, for example, included. A program that answer a request in 3 second does not do the same thing as a program that answer the exact same request in 3 minutes.
Suppose we have two examples of programs that do X (whatever X may be). Suppose the first program is slightly longer, but takes less time to produce. I would argue that typically the first program produces more value than the second just by virtue of having existed longer.
Or, suppose we have two programs that do X. The first program is slightly longer, but easily extended to do Y as well as X. The second program does X equally as well as the first, but is not as extensible to also do Y. If Y is a thing that is worth doing (i.e. doing Y produces value), then the first program is better than the first.
One more example: suppose the same program to do X can be written in two different languages, but programmers who know language 1 are easier to find and cost less to employ than those who know language 2. Even if the program is longer in language 1, it's probably better to write the program in language 1 rather than language 2.
My point is that there are so many externalities beyond "a non-obfuscated program that does X" that affect how much value a piece of software is going to create, that length of the program is often not a primary concern.
> Suppose the first program is slightly longer, but takes less time to produce.
Then you may want to produce a lesser code. That's fine. You understand that it's not because it takes less time to produce a code that it is any better. Young wines are lesser than old ones, yet you may decide to drink young wines instead.
> The first program is slightly longer, but easily extended to do Y as well as X.
Thanks for this. So here the trick is that you can count X and Y as things that the program does. It's exactly like in accountability. Note that this trick is more powerful that it sounds at first because it gives actually a guidance to when you're over engineering and when you are not. Over engineering is then when you write a longer code than it should for the reason that X is something the program does when it's not. Like in accountability, you can sometimes extrapolate a little bit the results but not stretch them to far.
> suppose the same program to do X can be written in two different languages, but programmers who know language 1 are easier to find and cost less to employ than those who know language 2
Then, again, you may want to produce lesser code - which is none of anyone business. It is up to you to judge what is more profitable: produce a lesser code or buy more expensive programmers - in practice, this is misjudged tremendously by many.
I'm no expert but it seems to me that the relative value of two programs (or functions or classes or whatevers) can be determined by only their LOC count only in the most trivial cases - e.g., a class that uses a single construtor/parameter signature and performs a single task under a single set of conditions.
If the logic has to handle multiple, possibly overlapping parameters and branching conditions in order to "do the same thing", then the longer code may well "outperform" the shorter one by whatever metric is most relevant to the use case (e.g., perform faster, use less energy, use less memory, be more readable, maintainable, portable, secure, or any weighted or unweighted combination of such metrics).
So yeah, it seems there is a recurring mistake / misunderstanding, you are not the only one. Two programs that have different performances for a given task for example do not do the same thing. Two programs do the same thing when their behaviour is, in everything (every metric), the same.
The lemma says: take two programs that does the same thing, one of the sources is shorter means you can attribute a produced-value (call that how you want) per line of code.
Then the theorem says: take any two programs (linux and gcc for example), the code that has, in average, the more value per line, is greater. (You have to trust that one of the two programs has, in average, more value per line of code because they have an average value says the lemma.)
Now you can say that a practice that tend to decrease the number of line of code is a good practice while the other that tends to increase the number of line of code is a bad practice assuming the resulting programs would do the same thing.
The thing is that in most situations the resulting programs are assumed to be doing the same thing. For example, when you choose between object-oriented versus functional programming, you are likely to be making a choice having a common resulting program in mind. If it's not the case, like for example, you worry that performances are not going to be good enough using this or that method, then it's indeed perfectly fine to choose the method that allows you to write the right program.
17 comments
[ 2.5 ms ] story [ 45.0 ms ] threadFor some software, higher performance is more valuable than fewer lines of code. For example, if you re-wrote the Linux kernel in Lisp, it might have many fewer lines of code than the current C version, but would deliver less value because it would run much slower and might stop for garbage collection in the middle of an interrupt handler. Concerns about real-time performance and memory-usage would also apply to lots of embedded software, like the code that controls the engine in your car.
I'm not sure that I'd call something a "fundamental theorem of software development" if there are large classes of software that it doesn't apply to.
I suggest you re-read the lemma. The point is about having fewer lines of code for what the program is supposed to do. For example, one could probably not write a kernel that does exactly what the linux kernel does (that has the exact same behavior [1]) but with dramatically less lines of code.
[1] the performances of the linux kernel are part of what that program does
What in particular do you mean when you say A is "greater"?
We ultimately don't have to prove it. We only have to agree together. (Another way of saying this is that it's unprovable, but every programming master will tell you it's true)
I'd suggest that this lemma doesn't quite take into account that software quality isn't just about what it is able to do today, but how efficiently it's able to adapt or be repaired in the future.
I agree with the principle behind it, which I believe to be "all else being equal, fewer lines of code is better than more lines of code," but I'd argue that all else is rarely equal. Sometimes, spelling things out in a slightly more verbose way is better than using some slick one-liner.
When I was in grad school, I was that guy who would strive to get his proofs as short as possible, but no shorter. Since my audience consisted of fellow students (who could be expected to be at least as capable as me), and PhD mathematicians, a short, clever proof had much higher value than a long, plodding argument. (But, even the short proof needed to be understandable: I recall reading a paper co-authored by several famous mathematicians that included a diagram to show the structure of the proof, not the mathematical objects that were the subject of the proof!)
Software is not mathematics and it shouldn't be treated as such. Remember that code is read many more times than it is written; and that the audience is the people who will come behind you and read the code, not the compiler.
> Sometimes, spelling things out in a slightly more verbose way is better than using some slick one-liner.
I think you may have missed some details here. First, the code must be non-obfuscated. Here is the trick: you decide actually when the code is obfuscated. When it is, you probably want a more verbose code indeed.
You understand that, at some point in time, it may be hard for a programmer, you, to judge if your code is obfuscated or if it is actually weak code. If other programmers feel fine with the slick one-liner, the theorem would suggest that it might be useful for you to learn to read easily that kind of code because you may be actually writing weak code.
Finally on this: local exceptions are ok. It's all about averages.
> "all else being equal, fewer lines of code is better than more lines of code," but I'd argue that all else is rarely equal
I believe you make a little mistake here. It not all else being equal. It's for a program that does x. For a program that does x, fewer lines of code is better. Please note that, "does x" includes the complete behaviour of the program, performances, for example, included. A program that answer a request in 3 second does not do the same thing as a program that answer the exact same request in 3 minutes.
Suppose we have two examples of programs that do X (whatever X may be). Suppose the first program is slightly longer, but takes less time to produce. I would argue that typically the first program produces more value than the second just by virtue of having existed longer.
Or, suppose we have two programs that do X. The first program is slightly longer, but easily extended to do Y as well as X. The second program does X equally as well as the first, but is not as extensible to also do Y. If Y is a thing that is worth doing (i.e. doing Y produces value), then the first program is better than the first.
One more example: suppose the same program to do X can be written in two different languages, but programmers who know language 1 are easier to find and cost less to employ than those who know language 2. Even if the program is longer in language 1, it's probably better to write the program in language 1 rather than language 2.
My point is that there are so many externalities beyond "a non-obfuscated program that does X" that affect how much value a piece of software is going to create, that length of the program is often not a primary concern.
Then you may want to produce a lesser code. That's fine. You understand that it's not because it takes less time to produce a code that it is any better. Young wines are lesser than old ones, yet you may decide to drink young wines instead.
> The first program is slightly longer, but easily extended to do Y as well as X.
Thanks for this. So here the trick is that you can count X and Y as things that the program does. It's exactly like in accountability. Note that this trick is more powerful that it sounds at first because it gives actually a guidance to when you're over engineering and when you are not. Over engineering is then when you write a longer code than it should for the reason that X is something the program does when it's not. Like in accountability, you can sometimes extrapolate a little bit the results but not stretch them to far.
> suppose the same program to do X can be written in two different languages, but programmers who know language 1 are easier to find and cost less to employ than those who know language 2
Then, again, you may want to produce lesser code - which is none of anyone business. It is up to you to judge what is more profitable: produce a lesser code or buy more expensive programmers - in practice, this is misjudged tremendously by many.
If the logic has to handle multiple, possibly overlapping parameters and branching conditions in order to "do the same thing", then the longer code may well "outperform" the shorter one by whatever metric is most relevant to the use case (e.g., perform faster, use less energy, use less memory, be more readable, maintainable, portable, secure, or any weighted or unweighted combination of such metrics).
Does this make sense or am I missing something??
The lemma says: take two programs that does the same thing, one of the sources is shorter means you can attribute a produced-value (call that how you want) per line of code.
Then the theorem says: take any two programs (linux and gcc for example), the code that has, in average, the more value per line, is greater. (You have to trust that one of the two programs has, in average, more value per line of code because they have an average value says the lemma.)
Now you can say that a practice that tend to decrease the number of line of code is a good practice while the other that tends to increase the number of line of code is a bad practice assuming the resulting programs would do the same thing.
The thing is that in most situations the resulting programs are assumed to be doing the same thing. For example, when you choose between object-oriented versus functional programming, you are likely to be making a choice having a common resulting program in mind. If it's not the case, like for example, you worry that performances are not going to be good enough using this or that method, then it's indeed perfectly fine to choose the method that allows you to write the right program.