4 ms·
> You have to simulate in your mind how the program’s going to work, and you have to have a complete grasp of how the various pieces of the program work togethe
by reedlaw 13y ago
> You have to simulate in your mind how the program’s going to work, and you have to have a complete grasp of how the various pieces of the program work together.
> You’ve got to have somebody who’s super smart. A great programmer thinks about the program on a constant basis, whether driving or eating. That method takes an incredible amount of mental energy.
> Before I sit down to code something, most of the instructions have already run through my head.
> Programming takes an incredible amount of energy, so most programmers are fairly young.
It may be a bit anachronistic to look at statements like these in the light of subsequent revolutions in software development such as XP and Agile. But I can't help thinking as I read this that he's doing it wrong. All the talk about using lots of mental energy to "have a complete grasp" of the program is fairly useless when faced with ever increasing complexity and code base size. Test Driven Development and clean code organization goes a long way towards breaking large problems down into easier to manager parts.
- andyroid 13y agoSo instead of that 300 line function you'll need to have a complete grasp over thirty 10 line functions and how they connect to do what you want. Yes, that is perhaps an improvement, but his point still stands. Just because you isolate certain units does not mean that a mental model of the entire program flow is "fairly useless". The majority of the software that I use (that I know of) is developed outside of the Agile/XP "revolution", and it seems to be doing just fine.
- gus_massa 13y agoJust be sure that each one of the 30 function is doing something interesting and obvious at the same time. For example, if your language lacks a CopyTagedMatrix then you just write one, it gets the correct size, allocates the memory if necessary, copy the elements and return the new matrix. Now you can use it without remembering the implementation details, and it’s much clearer than the 10 lines that necessary to get the bounds and the fors to iterate over the matrix. An extreme example is the GMP bignum library. You use each function as magic, and never read the implementation details. (Unless it’s in a very tight loop in a very hot part of the most important feature of your program, but I doubt that it’s good to use GMP in that place.)
- reedlaw 13y agoCan someone have a complete grasp over the 15M lines of code in the Linux kernel?
- 6cxs2hd6 13y agoI think his observation is relevant at any level of abstraction. Gates had a complete sense in his head of how his program worked at the level of machine language. But not at a lower level of CPU microcode, or transistors. So even he, even then, was not claiming to have "total" understanding in the sense I think you mean. Likewise if the Linux kernel (or your distributed web app) is organized into a reasonable set of "chunks", then it is possible to have usefully complete sense of how it works. The implication being that if it's not organized -- or organizable -- like that, you have a problem.
- brianpgordon 13y ago> Programs today get very fat; the enhancements tend to slow the program down because people put in special checks. When they want to add some feature, they’ll just stick in these checks without thinking about how they might slow the thing down. You have to have a programmer who knows the program inside out to guard against that. This one struck me. Today the public methods of a class would check to make sure the inputs are valid. Back then the programmer would just know the location of every single caller and make sure the calls are always valid in the first place. It's clear that the modern approach is a winner, especially with enterprise-size codebases, and really especially when developers churn every few years and nobody is around from when the code was originally written. And of course Amazon is the ultimate success story of taking this idea to the extreme with a completely service-oriented architecture. Coding super defensively to minimal interfaces has been proven to work.
- pjump 13y agoFor them special cases, you've got CTR+ALT+DELETE. :-D
- ANTSANTS 13y agoKeep in mind that Bill was talking about programming in assembly language for extremely resource-constrained systems there. Even today, if you're trying to write an extremely small/fast program/inner loop in assembly, you had better be relying on "dangerous assumptions" like that, or else the result is going to be worse than what a compiler could do.
- Symmetry 13y agoIdeally you want your type system to enforce as many of these assumptions as possible since when it can you both speed and safety.
- sirmarksalot 13y ago> This one struck me. Today the public methods of a class would check to make sure the inputs are valid. Back then the programmer would just know the location of every single caller and make sure the calls are always valid in the first place. Personally, I would use the second option even today, with the caveat that there should be few, if any invalid inputs, what with type systems and OOP. If your method takes a string as a parameter, and can't handle every string that ever existed, then you really should be deserializing it into a data object of some kind, so that the compiler does the validation for you. If I'm developing some kind of API for public consumption, then I'll do input validation at the service boundary so that the consumer knows why it didn't work, but otherwise I'm a big proponent of the "just don't pass null" approach. Input validation on every function call bloats the code base, and is annoying to read through.