Programmer Competency Matrix: Do you use it when hiring?
starling-software.com
starling-software.com
Do you even realize how obnoxious and full of yourselves you sound?! Let's see: suppose I'm a person who ranks highly on a lot of the lines in your matrix. You expect me to send you a resume (which you say you won't really consider), then to rank myself on a 10-page matrix of skills and abilities (but you won't care much what I have to say), then to write some rather non-trivial sample programs for you, then to come to Vancouver, or maybe Tokyo (no mention of paying my expenses) and sign an NDA (a freaking NDA!) so that I can work on your code with you, and then you will decide if I'm worthy of working in a company which only mentions two people on its "About us" page, and then says that both of these people have left.
Please splash some cold water on your faces and realize that people with the sort of intelligence, knowledge, drive, and leadership skills that you imply you are seeking can pretty much write their own ticket. And it won't be a ticket to get into your company, which frankly doesn't sound like it's setting the world on fire.
http://www.starling-software.com/en/qam.html
What does it do? Who would use it? For what? I have absolutely no idea, and I don't think I'm the absolute dimmest light in the Christmas tree. They use totally general words like "component" without explaining what they mean to them in this context. A component could be an object which implements a specific API, or a set of files with version information attached, or whatever. I don't feel like I know anything about QAM after reading that page. And I don't feel like continuing to learn about it, either.
Anyway, I do realize that Starling had nothing to do with submitting this to HN, but I still think they deserve some flameage for the general sense smugness and self-congratulation which one gets from their website, especially since those don't seem be backed up by any world-beating performance.
"Smart and gets things done"
Although Warren Buffett has an important refinement to consider:
"Somebody once said that in looking for people to hire, you look for three qualities: integrity, intelligence, and energy. And if they don't have the first, the other two will kill you. You think about it; it's true. If you hire somebody without the first, you really want them to be dumb and lazy."
-----
Personally, I think there are some key indicators of how good a place to work is, and they all come down to time:
(1) how long does it take to compile and run the code ... there is simply no substitute when testing for actually running the code, and you should be frequently testing your assumptions. Faster is better. There is a point at which if it takes too long you will be punted from "the zone", and even good programmers will produce either much lower quality code or a greatly reduced quantity (of features fulfilled, I am not so naive as to believe that lines of code measures are important)
I've seen some real horror stories, upwards of half an hour to compile and run... twitch
(2) how long does it take to get a new programmer set up. There are four key hurdles here:
(2a) physically getting them a computer and login
(2b) setting up a development environment
(2c) getting access to shared resources (e.g. CVS passwords) and environments (e.g. dev server login)
(2d) ... forgot what this one was ...
NB: one of the few "Agile practices" that is worth the hot air and spittle is keeping an internal wiki that contains everything the new dev needs. And of course, the first thing you get the new guy to do is to update the wiki
(3) How long does it take the organization to admit to a mistake and change course. If there is a wonky requirement, and it takes weeks or months to get permission to fix it and/or change the spec, they've got issues.
“There are only four types of officers.
First, there are the lazy, stupid ones. Leave them alone, they do no harm.
Second, there are the hard-working intelligent ones. They make excellent staff officers, ensuring that every detail is properly considered.
Third, there are the hard-working, stupid ones. These people are a menace, and must be fired at once. They create irrelevant work for everybody.
Finally, there are the intelligent lazy ones. They are suited for the highest office.”
http://www.lockheedmartin.com/aeronautics/skunkworks/14rules...
I think the requirement to reward managers for having small (but effective) teams is particularly insightful. We know about Fred Brooks and the Mythical Man Month, and we explain to the managers of our projects that 9 women can't produce a baby in 1 month until we are blue in the face, but they never seem to 'get it'. Surely one of the core problems with them 'getting it', is that even if they really did 'get it', in most organizations the incentive is towards larger groups, not smaller groups.
Economists and psychologists have been telling us that incentives matter for a long time now, perhaps it is time to apply that to an organization structure in a genuinely scientific way.
http://news.ycombinator.com/item?id=232192 <- This one has comments
http://news.ycombinator.com/item?id=298135
http://news.ycombinator.com/item?id=554338 <- This one also has comments
http://news.ycombinator.com/item?id=1022394 <- This one has even more comments
Indiangeek comes first, so it is probably online the longest. Not to mention that the hacker news post about it is 881 days old, and is the second result on Google.
(he uses 'methods' somewhere also to talk about code organization. I hope we're not going to say 'it's Java/C++ centric because in C there are only 'functions'')
The table also mentioned Powershell, VS.Net and VBScript
> And finally even if all the examples were in Windows terms, I hope that someone given the responsibility to interview new hires would be able to abstract from examples to general principles.
That may be true but I think Unix is something any programmer should at least be aware of.
Mentioning a Windows-only technology doesn't make it Windows-centric.
Mentioning only a Windows-only technology? Now that's Windows-centric. However, I see no example of that in the list.
I bet nobody would flinch if they saw reference to a UNIX-exclusive technology, either. (I saw VSS was called out - but had this been written three years ealier, Git would be in that same boat.)
Selective quoting, much?
- The context in which it mentions VS.Net: "Limited to primary IDE (VS.Net, Eclipse etc.) "
- The context in which it mentions Powershell and VBScript: "Perl/Python/Ruby/VBScript/Powershell "
So it describes a number of alternatives, some of which are for Windows-only, and all of a sudden the table is 'Windows-centric'?
I mean if you don't like Windows, fine, I don't care. But playing ostrich for anything Windows is just ignorance, and I mean that not in the 'not knowing' sense, but in the 'not wanting to know and proud of it', the 'ignorant hick' sense.
The 18 upvotes (as of now) of the GP make me sad. It makes me feel like many people voting are offended by the table because they don't score very well on it, and are looking for a reason to dismiss it, and oh look - something about Windows, that must be bad, because anyone using Windows or programming for it must be a moron.
I don't agree with all the details in this table, either; but that's irrelevant. This is a conceptual framework, a skeleton to apply further critical thinking on. It's been around for years and has been repeatedly upgraded and refined. It's not perfect but it's at least something. Outright dismissals of attempts at making programming and software engineering more quantitative processes, and - dare I say it - more like 'real engineering', and especially the dismissals based on hype technology fetishism, hold back real progress down in the trenches.
(oh and yes, I'd subtract just as many point for not knowing what 'PowerShell' is as I would for not knowing what 'Ruby' is, if any, in any interviews I'd do around this chart.)
Hmm looks like I have to retract this part - I'd swear I read this at least 5 years ago in a slightly different version and that I'd seen several updated versions since then, but now I can only find it going to 2008 on indiangeek.com. So I probably misremembered that part.
Has the business skill to figure out the technical needs of the organization, and the political skill and motivation to introduce and deploy changes as needed.
"Has heard of them but never got the time."
"Maintains a blog in which personal insights and thoughts on programming are shared"
Why do I care if someone writes a blog or not?
There are some pretty bad blogs out there and, IMHO at least, it wouldn't take much to write something which was worse than not writing at all. Caring about your craft is good but whether they're actually good at their craft is best judged by the content of what they are posting rather than it's mere existence.
It can also mean they'd rather write blogs than code.
Obviously it depends, but I don't think having a blog is necessarily a bonus and could well be a negative.
I'm gonna assume that this "programmer competency matrix" is a "How similar are you to me?" matrix. Skill sets which the table author lacks are missing entirely, and for other skill sets the precise skill level which the author happens to have is the highest possible level.
a) another way you can assess their programming knowledge b) a net benefit for your company's PR c) an indication they will help others learn
Kinda like that.
I'm still not sure of your argument; if you've heard of the higher level concept but don't know the fundamentals, that obviously still says something about your skill level and drives as a software engineer. It's kinda useless to try to list what exactly it could mean in this concrete example, the point is that the model allows systematic evaluation of skills.
Each node has a piece of data, and a pointer to the next node (or null if you've reached the end of the list). In a doubly linked list the nodes also has a pointer to the previous node.
This structure lets you build a list of arbitrary length without having to know in advance how much memory to assign it. You can append and iterate over elements in O(1), however seeking to an individual list element is O(n).
Most dynamic languages do not make much use of linked lists since it is easier just to use dynamically resized arrays. Any time you fill it you allocate a new array that is, say, 20% bigger and move the data. These allow you to seek to any element (including the next one) in O(1) with better average performance than linked lists. They also let you append in amortized average O(1) cost. Meaning that when you average out the cost of n appends, the overhead is O(n). However that cost is born unfairly, most are cheap but very occasionally you need to allocate the next bigger array and move existing data. For many applications (eg building a web page) this is fine. But if you're working in real time code then amortized average O(1) is not the same as O(1), and you must use a linked list.
There, now you know what a linked list is.
The most useful part about this tool, in fact, is not the specifics, but to see how the candidate rates himself, and compare your rating of his skills and experience to his own. If your rating and his come out radically different, one of you has a problem. :-)
I ask, because I feel it is a weakness in my knowledge base, and would like to see the steps to improve my learning in that area.
Systems-level security programming is outside of my domain. Anyone want to chime in?
Level 2^n: uses string concatenation in his SQL, for web forms passes plaintext passwords around in Javascript, has already been rooted and doesn't know it.
Level n^2: uses stored procedures, knows that cross site scripting and sql injection is bad, stores passwords in a form other than plain text, may block certain kinds of 'naughty' inputs (e.g. http://xkcd.com/327/ )
Level n: uses whitelists to validate input, does not use windows or SQL Server for anything, understands that security has a price (eternal vigilance) can explain what salting and hashing are, can protect your password against malicious database admin.
Level log(n): can protect against social engineering, audits OpenBSD for jollies, has transcended the need for users to create accounts and enter passwords, is completely unable to communicate with outside world since all their email has been PGP encrypted since the late 90s.
Level n: as much as I dislike it, Windows' security isn't actually all that bad nowadays. This, of course, assumes that you don't ever start IE, install no Adobe products, configure it properly, etc - but that's common sense for a server. Also, "eternal vigilance"? I think you need one patch to make a five-year old OpenBSD server as secure as pretty much any other system out there.
Level log(n): again, you can be pretty secure without being completely useless. Should include HMAC and PBKDF2/OpenBSD's Blowfish scheme/scrypt. May include full-disk encryption.
I do however stand 100% behind the eternal vigilance comment.
I wasn't expecting an example so quickly, but this serves as a case in point:
Anyone who is half sensible won't be doing either of these so I'm not sure what it proves.
YMMV.
They all have to be taken with a grain of salt, and considered as a tool for people to craft their own matrices.
http://mikevallotton.wordpress.com/2009/07/25/are-you-a-comp...
I think I'll print this off, put it on my wall and use it as a road map for the next ten years (ok, maybe not on the wall, maybe in a drawer where nobody else gets to see it until it's finished ;) )
Instead, you're buying him/her dinner a nice restaurant and you will discuss how each of you can come up with a mutual agreement that benefits you both, like any other deal between equals.
More importantly, this "matrix" was clearly written by a programmer, and not a business thinker. There is no way I would even give a rat's ass if a candidate used menus or keyboard shortcuts in an IDE, any more than I'd care which side they part their hair on.
What's left out:
Communication: - Can not only communicate clearly, but can adapt language to a given situation to ensure clarity without creating offence. Understands not everyone is a programmer, and doesn't fault them for it.
Business: - Understands normal business flows and how computer programs can make these flows more efficient. - Knows when to call it shippable and move on - Understands that favorite os/language/platform is not used exclusively, and doesn't intend to rewrite entire systems because the output is a period instead of a comma.
etc, etc.
I really don't care about most things on that list, as long as someone has the ability to grasp the concepts, the tools and experience to learn the things that are relevant, and few bad habits. Obviously someone down the left column is going to take longer to come on board, and it may be an indication of an inability or unwillingness/lack of motivation.
That is why the matrix is conveniently broken into specific sections.
Yes, it most certainly does. In the long run, the developer with the better grasp of fundamentals (e.g., discrete maths, data structures, algorithms and so on) will produce better code. NB, I'm not saying that the "naive" web coder can't produce good code. Nor am I implying that CS education always makes you a better developer. On average, however, that's exactly the case.
Even with generic web 2.0 stuff.
1) Do you receive magic fairy dust during college that makes you more productive and removes bugs from your code? No, I don't think so.
2) Will someone who knows the things taught in a typical 4-year undergraduate CS education be a better web developer? Obviously (?) yes; you can look at any of them and clearly see that they are good things to know. Will you point to some particular thing that you think is useless? Let me list some that seem reasonable for a lot of web development: non-trivial data structures, for understanding databases; experience with multiple languages; continuation-passing style; general system and network architecture (e.g. the OSI model) -- and so on.
If by "web developer" you mean writing http://www.hasthelhcdestroyedtheearth.com/ then I guess no, you don't need to know much about anything for that.
Your post is missing any supporting arguments for this claim.
I know a lot of 'Rails guys' and their dreams certainly aren't crashing down. If anything, they enjoy their lives more because their programming education has been focused on making things, before making things fast.
Conversely, there's a lot of guys with CS degrees who ended up jaded with the idea of making things and became Unix admins, mid-level managers, or PMs.
We all know rails has problems with scale, and that these problems can be overcome. The way to overcome these problems is through optimal and performant coding/data-storage patterns, and to practice these one requires knowledge of CS-type matters.
Now Rails or Rails-esque apps obviously will not encounter these issues until they reach a certain size. Therefore unless one has the requisite CS-style acumen, one's projects have a cap on their maximum success/popularity.
Assuming that when we say "dreams" we are referring to hackers' projects becoming big and successful and popular, (thats what everyone around here seems to dream about,) they will not be realized without someone around who knows their big O from their divide and conquer.
If you can make something (or likely many things, quickly) you can be lucky enough to get the point where scale is a problem. At which point you can pick up these skills where you need them - they're not difficult, especially if they directly apply to a problem domain you're working on rather than a arbitrary one.
The Rails guys I know who these issues typically end up with a quick move to JRuby and pick up what they need.
If you can't make something quickly, all the premature optimization won't help you with the problems you'll never have.
I also believe that teaching algorithms before logic and engineering concepts is wrong.
I would rather hire someone who has made more apps than someone who has excellent knowledge of algorithms but has made no apps. Would you?
This is rather a false dichotomy, isn't it? Who can obtain "excellent" knowledge of algorithms without ever making anything? Very few people can learn so much without ever doing.
Nobody is suggesting that it's better to not make something than to make something. The real suggestion is that it's better to make something good that you won't have to throw out later than to make something substandard, born of ignorance. Having reasonable background knowledge about algorithms, data structures, and architecture makes it much easier to get it right than if you're solving those problems as you come to them.
> Nobody is suggesting that it's better to not make something than to make something.
Certainly. But they do focus on optimization as the core of programming. It isn't - turning logical problems into code - aka, making programs - is.
However, I think your specific example doesn't reflect the argument I imagined you making. Your comparison is someone smart who doesn't know the tools (Ruby, Rails, Javascript) with someone who knows them well. If it were a short project, at least, I agree with you; I'd probably take the guy who knows the tools.
In all my career in computing and related work, I've participated in interviewing for hiring and evaluating the candidates, and I hope to be hiring next year.
So, would I take that 'matrix' seriously in hiring?
Not really!
Looking back, some of my thoughts on hiring were wrong! I suspect that using that matrix would also prove to be not very good!
Some of the stuff in the matrix is okay to know but, really, next to trivial to learn: E.g., early in my career I skimmed through all three of Knuth's three volumes of 'The Art of Computer Programming' and studied fairly carefully his volume 'Sorting and Searching' and there sorting and trees. I programmed a lot of that material -- heap sort, quick sort, Shell sort, merge sort, binary search, minimum spanning trees, etc. -- for my career.
Eventually I got a lecture from S. Kosaraju, and he covered all those high spots in a one hour lecture. I already knew the material, but it was nice to see that it could all be covered in an hour. So, really, for the 'computer science' material, mostly all that a person might be missing is one or a few lectures of an hour each. Not a biggie.
Curiously the matrix mentions dynamic programming. Okay. It's a nice idea, with various versions and applications. E.g., it is the core of one of the more important network shortest path algorithms.
One of the nicest parts of dynamic programming is that it is the core of 'stochastic optimal control', that is, best decision making over time under uncertainty, and, thus, one of the most general approaches to 'real time control'.
To make this 'approach' solid mathematically, really need to address the subject as Markov decision processes since the Markov assumption is really what makes the crucial 'decomposition' into 'stages' justified. So, for much more on the Markov connection, there is
E. B. Dynkin and A. A. Yushkevich, 'Controlled Markov Processes', ISBN 0-387-90387-9, Springer-Verlag, Berlin.
Once I had a practical problem that could use these ideas, got a 90 second lecture on the subject from George L. Nemhauser as in
'Dynamic Programming', ISBN 0-471-63150-7, John Wiley and Sons, New York.
had to run to catch a plane, and by the time the plane landed basically saw how that worked. It's nice. After an advanced course, I worked harder on the math (e.g., the tricky subject of 'measurable selection'), the 'computational complexity' (commonly a problem), and some applications and wrote my Ph.D. dissertation in the field. So, George 'directed' my Ph.D. dissertation in 90 seconds before I started grad school! Thanks George. Actually he liked what I wrote and chided me for not publishing it. I didn't want to publish it; I wanted to sell it!
Dynamic programming is a nice subject, but in hiring I wouldn't vote anyone down for not knowing it. I would vote someone down for thinking that dynamic programming is a biggie. If you don't know the basic idea of dynamic programming, then study the topic for an hour or so and you will get the idea. If want to get deeper into the subject, work through, say,
Stuart E. Dreyfus and Averill M. Law, 'The Art and Theory of Dynamic Programming', ISBN 0-12-221860-4, Academic Press.
and notice the 'deterministic equivalence' for the case of 'linear plant' (the system being 'controlled'), quadratic objective function (say, reduce cost or risk), and Gaussian exogenous effects (the 'stochastic' part trying to 'control' against) -- called the LQG case. So, there 'deterministic equivalence' can save "a pant load" of computer time. For more look at the papers of R. Rockafellar at U. Washington.
So, just above I totally 'blow away' the mention of 'dynamic programming' in the matrix. But, again, the subject is just not very important for hiring.
Somewhere in that matrix is mention of 'system monitoring'. Yes, there is some importance here. Once I worked in a high end project applying 'artificial intelligence' to 'system monitoring', did some 'architectural' work, wrote some tricky code that helped the project a lot (won an award), and then took a very different direction, did some original research, and published a paper in a peer-reviewed journal. At one point the work needed a multi-dimensional 'nearest neighbors' search algorithm, so I did something like binary search on each of the several dimensions. Later I discovered that I had reinvented k-D trees -- k-dimensional binary search trees. So, there is a tree, and do a depth first traversal. But then have to do a 'depth-first backtrack traversal' of a containing 'subtree' with some 'cutting planes' to be sure have found the actual 'nearest neighbor' or, if desired, the 'k nearest neighbors' for some positive integer k (not the same k as in k-D!). In the end the work became, from all I can tell, the first, and quite general, approach to multi-dimensional, distribution-free statistical hypothesis testing (which 'system monitoring' has to be close to). Okay. So, here 'blow away' the matrix on 'system monitoring'. But I wouldn't hire based on such work.
The matrix is big on 'integrated development environments' (IDEs), but so far I've seen no good reason in MY work to use them and some big reasons not to: I do my programming depending heavily on (1) the hierarchical file system to support an implicit 'taxonomic hierarchy' of 'nested' work, now, finally, being appreciated by Microsoft in how 'XCOPY deployment' and IIS use subdirectories (and they can do still more with good use of file system 'access control lists'), (2) a scripting language for command line scripts (easy enough to type at a command line and then really easy to drive from more scripts!), and (3) the one, same programmable text editor I use for as much as possible of everything I type and read.
So, with the file system, scripts, and an editor, I get to do essentially all my programming using just a few good tools I know well and can use for much more, e.g., writing papers in TeX, doing projects, keeping notes, writing e-mail and this post, etc. So here are a few tools easy to use that, for MY work, work great. Have about as much chance of getting me to give up my favorite programmable text editor as getting a violinist to give up a Strad; moreover, the violinist does essentially all his music with his Strad, and I do essentially all my typing with my text editor. Sorry 'bout that IDE developers!
In more detail, I had to pick an operating system I would use as the main one for my work -- I picked Windows. Then I had to pick a compiled language -- I picked Visual Basic .NET (VB).
Then to develop VB code I discovered that actually the VB compiler is in file VBC.EXE. Then if install .NET Framework 2.0, 3.0, 3.5, 4.0, etc., in each of them is just one file, VBC.EXE, and it IS the VB compiler. To run it, just RUN it by having a simple script give the full tree name on a 'command line'. The options needed are minimal. The compiler seems to be fast and to generate small EXE files. I find the error messages to be good. So far I've found no bugs at all. It's easy to suppress many sources of problems with just the source code statements
Option Strict On
Option Explicit On
Works fine. For MY work, I don't see that an IDE could be much better.
For interactive debugging? So far I've not needed it and have not looked at what is available.
Why VB? Because it has very little 'idiosyncratic syntax' and more generally is easy to read on the page, and it offers essentially full access to .NET and its ASP.NET for Web site development and ADO.NET for relational data base access. Its 'object model' based heavily on 'interfaces' is SIMPLE but powerful enough. Its 'managed memory' can be a big help. The complier is fast. The complied code is plenty efficient. Good enough. Decision done.
For an IDE, I've seen several of them. Each is a complicated new tool to learn with a lot of time and effort for the learning. Generally the documentation just SUCKS: E.g., I never could find any clear statement of what Microsoft meant by a 'dockable' window or why I should care, and I very much did NOT want to figure it out.
Then there is the issue of how to write macros for the IDE and/or how to script the work, and I've so far never seen how to do that or any reasonably clear documentation for how. Then there's the issue of what the heck is the IDE doing for (to!) me -- I don't know, and won't know. And when what it does for me no longer works, guess who gets to diagnose and fix the problem? So I would be depending on something complicated I don't understand and, then, have to fix it, when I don't understand it. Then in the first few trials I saw that just for a program "Hello World" the IDE created a big subdirectory tree with maybe 50 MB of who knows what the heck; when things didn't work, I'd have to work with all that glop, gorp, and goop -- NO THANKS.
Uh, long ago I discovered that the key to 'ease of use' is not some tool doing a lot for (to) me but just a tool that is reliable, well documented, easy to 'script', and easy to understand. Thus, I don't want an IDE! Uh, in my kitchen, I REALLY like my 10" classic French chef's knife and various cutting boards, and I want no Rube Goldberg contraption just for cutting onions, another just for slicing carrots, another just for shredding cabbage. Similarly for software tools.
The matrix omitted some of what I do consider crucial in programming:
First, in the work, what is most important is the significant 'meaning'. There is, so far on this planet, exactly one way to record and communicate meaning -- a natural language, and of these, now, the most important is also my native language, English. So, I want the important 'meaning' to be recorded and communicated in English. Math? Actually, when done well, e.g., by P. Halmos, it is written in complete sentences. Same for mathematical physics. The symbols? They don't mean anything until carefully described in the natural language and, then, remain essentially as just abbreviations for the natural language definitions, descriptions, explanations, and examples. To be more clear, the symbols and the source code, without the English, mean NOTHING, mean zip, zilch, zero. Don't fool yourself into thinking otherwise. I don't say this because I like English literature (I HATE it) or hate math (my field is really applied math, and I do like it); I say this because it is what I have concluded is true. Knuth's old idea of 'literate programming' may be close.
So, some of the best examples of how to communicate 'meaning', ESPECIALLY about technical material, in English are in good college texts in, say, math or mathematical physics.
That's where we have to start on 'meaning'.
Second the work of software is to create 'systems' that have useful 'meaning'. So, this meaning needs to be recorded and communicated, for both developers and users, in English. There is NO substitute: Here are software techniques that are sometimes helpful -- long, mnemonic symbol names; pretty printing of source code; software 'objects'; IDE GUI 'panels'; software 'functions' and/or 'functional programming'; 'declarative' programming; desktop GUI UI 'icons' and 'windows' -- but none of these has meaning or is a substitute for English for recording and communicating meaning. Sorry 'bout that.
In particular, to me source code should read much like a good college text in math or mathematical physics. So, the English is in the source code 'comments'. On first reading the source code file, read just the comments. The code itself has no meaning. Even 'object oriented' code with long, mnemonic symbol names has no meaning. The meaning depends heavily on the English in the comments. In well written software, between the code and the comments, far and away the comments are the more important.
Commonly well written technical material has references that provide support for smaller details. Good. So source code should have such references, and mine does: My code is awash in file system tree names of files of documentation, mine or otherwise usually an HTM file of a Web page. For my source code in my favorite programmable editor, one keystroke displays a reference.
All the crucial issues, e.g., checking the inputs, the 'edge cases', issues of 'memory leaks' and threads, should be discussed in English in the comments with explanations of how the issues have been handled.
Yes, more important than code with English comments can be 'external' documentation all in English with no code at all! Then, of course, in appropriate places the code comments will reference the external documentation.
Net, by far the most important typing in software is the English documentation, NOT the 'code'.
For 'source code control systems', I can believe that in some projects, although maybe ones a bit too large to be effective, such tools could be useful. However I've been on significant software projects with eight or so people, and we did well with no such tools at all.
For my work now, everything particular to some one 'version' of the software is in a file system directory subtree. Then for a new version of that software, I start by just making a copy of that subtree; then I document, right, in English, the purpose of the copy and go to work on the copy. Works well.
Next, to me the most important lesson in work that needs software is to be clear on what the work is and what contribution the software is to make to the work.
Next, for the software, the most important need is to describe what, in terms of the real work, the software is to do.
Next, within the software, the most important step is to use 'divide and conquer': At one point in Rome in the Middle Ages, there was a big project to move a large, stone monolith some dozens of feet in a plaza. Big project. Complicated. Expensive. Famous.
But, before getting too impressed, how the heck did that rock get there in the first place? Over 1000 years earlier, Caligula's slaves cut the rock as one piece somewhere in the headwaters of the Nile, floated it down the Nile, across the Mediterranean, and to Rome and put it in place.
How'd they do that? They used 'divide and conquer', that is, broke the whole project into pieces, broken into pieces, etc., until each of the pieces was doable. What else? Summon spirits from the vastly deep?
Same for software: Break the work into doable pieces. Hopefully each piece is easy to understand, document, code, test, and modify and likely changes in what the software is to do need affect only a few pieces. That's it.
Next, for getting people productive in programming, my experience is that someone, maybe the project leader, needs to have cut through the millions of acres of swamp of glop, gorp, and goop and gotten the work and the tools all simple, clear, and easy to understand. Then can take a bright, well motivated person with no background in programming at all and in a few hours of instruction get them quite productive. The person needs to know how to read with understanding, learn, analyze, and create meaning by writing English.
So, in interviewing, I want such a person. 'Dynamic programming' and Knuth's 'Sorting and Searching' or 'functional programming'? I don't care.
How 'bout that!
Ditto for source control. It's fantastic to have a complete history of changes with date and blame attached, along with comments for explanation. It's like an automatic logbook for the code, with free unlimited "undos" to boot. I can't imagine working without it, even in a one-developer project.
Perhaps I'm just spoiled -- AKA "Kids these days can't lance a pimple without an automatic vibrating scalpel with drain and suture" -- but these are the tools that make me more productive. I can do more better in less time.
I'm not a fan of English docs either; they fall out of date very quickly. I'd much rather have readable code, with things like sensible variable names and readable conditionals like if(noUser || userIsBusy) instead of if(user==nil || [userObject state]==kStateWaiting). I realize that readable code doesn't mean no docs, but I'd rather my colleagues spend an hour coding than a half on coding and a half on docs. I've seen too much code where the comments are flat-out wrong.
On interactive debugging, it's terrific stuff when it's needed. I've done a LOT of programming, and a few times I've used interactive debugging: When I needed it, it was terrific.
Net, I just haven't needed it very much. On my current project, I haven't needed it at all yet. I believe that I've written the challenging code, and I had no problems with debugging.
For some of the trickiest parts of the code, I just coded the operations twice, once a simple, slow way and once the faster, trickery way I wanted in the final version; then I had the code compare the results. I ran enough test cases to have good confidence that the two versions give the same, and correct, results. If the results were not the same, then to find the difference, instead of interactive debugging, I would have just 'desk checked' the code carefully. I find such desk checking terrific stuff -- each little possibility for a problem has to be checked, and sometimes more than one error is found. With interactive debugging, I can be tempted to quit checking when the first error is diagnosed for just that one test case -- not so good.
Or, "Joe, there's a bug in here somewhere. Find it with desk checking."! Or, "Mary, Joe says that this code is correct. Here's $1000: If you find an error, then you get the $1000; else Joe does."!
I wouldn't have coded just the tricky version and then tried to use interactive debugging to be sure the version was correct: My test cases were too extensive for checking 'interactively'.
For "I can't imagine adding print/log lines for every imaginable variable in a scenario.". I don't do that either or need to. Occasionally a few print or log file writes, in a small part of the code, say, where I just added some code and something doesn't work, have been enough.
Generally, though, any reasonably complex system should be able to report, at levels of detail requested in real time, what it is doing, and a lot of print or log statements are a start. In my most important code, I have such statements controlled by a variable that specifies 'message level', that is, the 'level' of detail of the messages. My intention is later to use Microsoft's code instrumentation infrastructure to send the contents of such statements to some 'system management' platform. So, generally I like 'messages' from code.
And, actually, in my testing, I have lots of such print statements executing. The output of a small test case can be some thousands of lines, and I explore them with the capabilities of my text editor; I wouldn't want to do that work with interactive debugging.
E.g., recently I had to reinstall the Microsoft software on my boot drive (grim story) so wanted to be sure my code would compile and run as before. So, for each directory of code, I made a copy of the directory and in the copy again ran the relevant scripts to compile the code and to run it on the test cases. Then I took the output, with its thousands of lines, and used a simple editor macro to do a line by line comparison of the new and old output files. Some lines were different because of time and date stamps or reports of allocated memory addresses. A few editor commands removed those lines, and then the old and new output compared perfectly. I can't see any easier or better way to do such a test; I want the print statements and don't want interactive debugging as a substitute there.
To me so far interactive debugging is so unimportant I haven't even taken the time see what is available with VB. I believe that somewhere I saw that VB has interactive debugging also via command lines; if so, then that should be the most I would want. But I haven't even looked.
Here are my 'source control' tools!
First, if I am making any change at all in an old program or any significant change in a program still under development, then I start with a new file. So, if the last version of the program was PROG013.VB, then the next version is PROG014.VB; that is, I copy file PROG013.VB to file PROG014.VB, put some explanatory documentation at the top of the file, and start making changes.
I don't don't even see the "014" -- I have an editor macro find that for me! My editor gives me a directory listing, and one keystroke sorts the files in descending order on time, and then PROG014.VB is right at the top of the list ready for work!
You mentioned "undos" -- that's PROG013.VB! Of course another source of 'undos' are the daily incremental disk backups! And another souce is just my text editor.
Second, for making changes in a program, typically I slap a time and date stamp on the change. So my editor does that, e.g.,
Modified at 01:32:46 on Wednesday, December 1st, 2010.
For source code files, the editor puts this line in as a comment, choosing the comment syntax based on the file extension.
So, I get time and date stamps, and that's close enough for me for a "logbook" of changes!
For "comments for explanation", I'm big on those!
For "I'm not a fan of English docs either":
Well, fundamentally there's no alternative: Again, as I wrote:
"There is, so far on this planet, exactly one way to record and communicate meaning -- a natural language, and of these, now, the most important is also my native language, English."
Fundamentally, that statement is just true. Sure, with enough detective work, decoding, etc., people commonly guess at the meaning given much less than what I described.
Other aids to understanding the meaning include mnemonic symbol names, pretty printing, and your "readable" code. Still, at least fundamentally, these aids cannot replace English as the source of meaning.
You wrote
if(noUser || userIsBusy)
Okay. For using English documentation, I gave as examples college texts in math and mathematical physics. In such books, the symbols are carefully defined and maybe also motivated, discussed, and illustrated. Then commonly the exposition can continue with some 20 lines of algebraic derivations without additional English. Your statement 'if' can be seen as parallel.
For your symbols
noUser userIsBusy
likely somewhere you specify the data 'type' of these as 'logical' or some such, and then your code can be plenty clear.
Yes, keeping the English documentation up with the code is a pain:
For an on-going development project, it can be tempting to rely on the fact that the team does know the code and delay a lot of documentation. But if the project goes on for many months, then staff can leave and leave the project short on what parts of the code 'mean', and new staff can arrive and be lost and nearly useless.
Further, at some point development slows and the software becomes an 'asset' of the company. For continuing value, there needs to be enough documentation so that a new team could with reasonable efficiency take over and 'maintain' the code. So, that new team needs, typically, quite a lot of good English documentation, both as comments in the code and as an external paper. So, before the original development team goes on to other work, it can be important to take one more pass over the code documentation and get it up to date and clear. Sorry 'bout that.
Generally on code and its internal documentation, Knuth's work on 'literate programming' is one polished way to proceed.
In particular, for the code I wrote a year ago, without reasonably good documentation I wouldn't know what the heck the code does or what I was thinking about.
Here's a related point on IDEs: Of course, can use SQL Server Management Studio to 'define' a database, that is, say what the tables are and for each table what the columns are. Yup, can do that! But I refuse to!
Instead I define the database using the T-SQL statements in a text file, and here's why: The text file has about as many blank lines just for 'readability' as T-SQL lines. Then the comments are about five times as many lines as the sum of the blank lines and T-SQL lines. These comments explain what the heck I had in mind for that database 'schema' (in the traditional sense, not really in the sense of SQL Server 2005 and later). So, when a table has a clustered key and also a separate index, the comments explain why. Etc.
So, that 'schema' with its documentation is a rock solid part of my project; as I write code to manipulate the database, all the code writing draws from the ONE, SAME documentation of the database as the code should.
If I typed the schema into the SQL Server Management Studio IDE, then I'd miss out on the documentation and the primary source of crucial 'meaning'.
GUIs have often been praised with "What you see is what you get", but there is a perceptive old response, "What you see is all you've got.".
Or, using SQL Server Management Studio to type symbol names into text boxes just does NOT create the crucially important meaning.
Sure, one way to be sure that English documentation is not "flat out wrong" is to omit all the English documentation! But I suspect that if you were to maintain code written by someone else, then you'd rather have more English documentation, possibly with some errors, than less.
Yes, important, undocumented code can be a form of job security! But for my 'job security' I want the code well documented because in two years the code may need some changes and I may be the person who has to make them.