I have a lot of experiments in there: different approaches to parsing; R/OCaml/Lua experiments; tests for interactions between Unix signals, processes, and threads; etc.
One thing I've also found useful is: whenever you see a neat code snippet on Hacker News or a blog, download the code, and write a shell script to build and demo it. You don't even have to understand it thoroughly the first time around. But when you come across something related in the future, your brain will remind you of it, and you will have a little shell script you forgot about to puzzle through :) It takes like 10 minutes each time.
I have 141 different subdirs; probably half are my own and half are demos I learned something from (or hopefully will in the future).
Not sure if that's what chubot meant, though.
And more often than not I add my own tests and demos. Sometimes I write a main() program, if it's C. If it's JS, then add an HTML skeleton and a script that runs a web server to demo it (e.g. python -m SimleHTTPServer). If it's Python, install any deps necessary. And often you will want to run the same script with many parameters to fully demo it.
The idea is to basically prove to yourself that the code works, without necessarily having to understand everything about it. Then when you see it later, your brain knows you can go back to it. You won't feel lazy like "oh man I have to go back and find the web page I saw 3 months ago, download code, pore through instructions to figure out how to build it". That part is already done.
For example, here's a snippet I did when testing out cityhash. It's usually much messier/longer than this.
run.sh:
#!/bin/bash
readonly CITY_SRC=~/src/cityhash-1.1.1
download() {
... <wget tarball> ...
}
hello() {
g++ -I$CITY_SRC -I$CITY_SRC/src -o hello $CITY_SRC/src/city.cc hello.cc
./hello "$@"
}
"$@"
hello.cc:
#include <cstdio>
#include <string.h> // strlen
#include "city.h"
int main(int argc, char** argv) {
if (argc >= 2) {
char* s = argv[1];
unsigned u = CityHash32(s, strlen(s));
printf("hash = %x\n", u);
return 3;
}
}
Then I just check those two files into ~/git/scratch/cityhash. Then I can reproduce it on any computer with a couple short commands.In particular, the following remarks from Gingold's essay complement the OP well: "My hard drive was full of failures. Twelve years after learning to program, I looked back on all my software: none of it was finished, and what was, wasn’t ambitious enough. The projects that started out ambitiously always seemed to fall back to earth, like failed rockets lacking the power to propel their own weight into orbit. Sure, there were interesting ideas in there, lots of wacky toys, and I had even attempted a few large projects, but none of them ever came together like the cool games and software I had always admired.
Sure, I had become a pretty good programmer, and learned to make cool stuff, but clearly none of it would ever amount to anything. I just didn’t have what it took.
I went to graduate school at Georgia Tech, and read some Chris Crawford. I learned that he had the same problem. But he didn’t think of it as failure. For him, this was an organic part of the development process. The failures filling his hard drive were actually “prototypes” that helped him decide which ideas were worth pursuing. For each good idea, there were a large number of stupid ones that didn’t work out. Failing, for this successful designer, was a way to find the good ideas. The revelation hit me like a ton of bricks. Maybe I had a chance after all... Master artists like Escher or Van Gogh don’t just sit down and crank out a finished piece. Artists create numerous sketches and studies before they undertake finished paintings, let alone masterpieces... All of my software failures, which I was now thinking about as prototypes, sketches, and studies, had taught me a thing or two about design and programming. If you want to learn to draw, you have to make a ton of bad drawings first. The difference between practice and failure is simply a matter of attitude."
These ideas are, of course, not new, but Gingold has thought about them deeply and distilled them sharply. The essay as a whole goes much further than the above excerpt, and is well worth reading.
I recently pulled out some code from over 20 years ago, an experiment in mixing fuzzy logic and Conway's Life that... didn't exactly work out. But it had some intriguing results. Was it a "failure"? Not in the least: it produced results that were intriguing enough for me to remember two decades later, even though it never "came to anything" in the meantime.
That said, I do like the word "failure", and I'm happy to say, "My hard drive is full of failures!" It just sounds better than "practice" and it challenges anyone I say it to. What can they say in reply?
The world is full of little people desperately attempting to tear you down. When you say, "My hard drive is full of failures" they have nothing to come back with. They know you've actually done something, which is more than they have. So go forth and embrace your failures. They prove you're alive, and doing something interesting with your life.
My attitude is in part informed by this quote: "One word characterized the most strenuous of the efforts for the advancement of science that I have made perseveringly during fifty-five years; that word is FAILURE" -- Sir William Thomson. If Lord Kelvin can fail, so can I, damnit!
But I think your link also helps me understand my strengths (and rationalize away my weaknesses :) All its examples are from games, which are by definition a short-lived genre of program with a constant churn of rewrite and reimplementation in a hit-driven business. I tend to obsess about system software, where code tends to accumulate slowly and huge swathes are never rewritten. In my domain it isn't being able to write software that's key, but being able to read other people's code. That's what I struggle with, and it's at least not obvious that these articles' approach helps with getting better at reading.
I return to the first paragraph of the OP: programming is too broad a field. I suspect we think of it as a field only because it's so incredibly young. It's quickly flowering into a foundational skill, on par with reading and writing (perhaps replacing 'rithmetic?) It's not a single domain, but all domains, each with its own subtly different emphasis on core skills, preferred paths of improvement, and likely failure modes. These articles aren't as comprehensive as I had first feared.
(I realize I'm not actually rebutting anything the articles said. Both are valuable and I'll continue to mull them. I'm just airing insecurity here.)
A REPL is more of a "scratchpad", to stay in the family of metaphors being used. Scratchpads and sketchbooks serve similar purposes, but the latter generally is used for things intended to have a bit more permanence and also to be capable of re-visiting.
In any case, I'm pretty sure the main point here is "you need to write a lot of varied code if you want to become an expert at software development".
(self-promotion here) or perhaps a polyglot code notebook: http://beakernotebook.com/
This is so true. A lot of the 'experienced' people I've met in the industry with 10 or 15 years behind them have done nothing but their jobs in that time to practice their art, and their 'experience' is therefore of such low quality that an exceptionally good junior with a few hobby projects behind them can outclass them even in their own specialist area.
I've worked with guys that have done nothing other than Spring and Hibernate for nearly a decade and they know those platforms inside and out. There's just no way someone junior with a few hobby projects are running rings around those guys in their areas.
However, if you take something new, or something these guys haven't used, then yea.... rings could be run. Other than that, I don't think so.
I'll trust my experience over guesswork.
Therefore, I'd rather have a sketchbook for ideas :)
> It takes ten-thousand hours to master your field, so the story goes, except that programming is too broad of a field.
If you've put in ten-thousand hours into the field of programming, you'll not need to put in another ten-thousand if you switch from, say, a vector-drawing tool to a music composition software. Yeah, you might miss some stuff like everything related to audio - but picking up the concepts and one or two related APIs should be two or three orders of magnitude quicker than "I'm learning to program".
Learning new concepts and APIs is meta-skill, and one will become better at it the more different concepts and APIs one has used.
You'll also need domain knowledge, of course. Again, working with domain experts and users is a meta-skill that you may want to train (or you may depend on someone in your team to do most of that for you, e.g. a Product Owner).
So, if someone has "mastered programming", she should be able to be dropped into an unknown domain and have the skill to identify and pick up the parts she is missing in a fraction of the time it took to "master programming". Mastery of a skill means the switching costs between domains is significantly reduced, but not zero. Same is true for a carpenter: Building a ship is different from building a house or a bridge, yet a master of carpentry will be able to pick up the skill of building a ship more quickly than, say, a master of programming would.
Most fields are too broad to know "everything" about, that is not specific about programming.