Post your suggestions in the comments!
Backstory: I realized recently that I had pretty much stopped consciously trying to spend time getting better at my job. Which is pretty silly since I’m still probably in the bottom 5% of programming experience—I clearly have a ways to go!
I’m trying a bunch of different projects to tackle this from different angles, and one of them is improving the tools I use. I’ve noticed in the past that some tools, or practices, have had a surprisingly large effect on the speed with which I can code or the number of bugs I make. (I’ve started the comments off with an example.)
Unfortunately, it’s hard to know what these will be before making the sometimes-substantial investments to learn them. So I’d love to know other folks’ thoughts here!
Comments
At least in the past year, my top pick would be programming in good interactive environments (eg IPython notebooks). They just make the write/run/figure-out-what-you-messed-up feedback loop so much shorter.
I didn’t used to work interactively very much because of a couple friction points:
You have to reload everything every time the code changes
It’s a pain to start up an environment (you have to import everything you want into your namespace, etc.)
But I recently discovered that IPython’s “autoreload” feature fixes the first one, and spent a little bit of time configuring a “harness” that did a bunch of set-up to solve the second one. That made it a lot easier to use.
If you work in a language that supports it, compilers with custom errors are a huge win. That is, compilers that with plugins that error on code that technically compiles according to the spec, but is almost certainly not what you want. http://errorprone.info/ for Java; http://clang.llvm.org/extra/clang-tidy.html for C++.
Example: http://errorprone.info/bugpattern/StringBuilderInitWithChar
In Java, new StringBuilder(“a”) creates a StringBuilder containing the character a. On the other hand, new StringBuilder(‘a’) creates a StringBuilder initialized to hold a String up to length 97, the ASCII value of ‘a’, which is just ridiculous. We cleaned up the codebase and turned it into a compile error so that will never happen again.
A solid runner-up (though not as dramatic) would be good autocompletion tools. These let me do a lot more without context-switching to look at documentation.
Specific recommendations:
for Emacs functions (and filenames and variables and a lot more stuff), helm
for Python in emacs, “jedi”
for shell, zsh (although I think bash has a completion package with a bunch of common completions as well, and fish might have better completions than zsh since it parses man pages, but I’ve never tried it)
The combination of (a) mass storage that was cheap enough that you could put source code on disk rather than paper tape or punch cards, and (b) CRT terminals with full-screen editors so that you weren’t using essentially comand-line tools to edit your source as though it was a deck of punch cards. Huge. I don’t think I’ll ever go back. ;-)
Wandered here from the magic of Facebook and Louis Wasserman woo
Efficiency improvement is something that I find really neat and interesting, because often it’s really easy (for me at least) to focus on large efforts for small gains over small efforts for large gains. You can get a lot of power from trying to see the act of writing code itself as a set of abstractions, and see how those can be automated. Here’s some stuff I found helps a lot:
Get really, really good at your editor. I see this a lot in terms of “learn vim”, and while I’m a huge fan of vim I think the same ideas apply to any editor. For example, in Sublime you can speed up a lot by just knowing ctrl-L (select line) and c-E c-G (go to next instance of word under cursor). And there’s always more to learn in any editor. I just learned how vim’s buffer list works and that’s been super handy.
If you use git, learn how to use a mergetool. Dear god it saves so much pain.
I’ve been pushing really hard at work for us to start doing test driven development and pair programming, and so far both of them have lead to lower-stress, higher-quality code.
vimium plus aggressive bookmarking plus the B command makes it much easier to look up services and resources online.
Exercise and get enough sleep, and remember that in the long run people are most efficient when they’re working only 40 hours a week.
(depending on the problem), thinking more before I type. sometimes this means letting my brain mull over a problem in the background for a couple of days before writing down the program.
writing out large-ish chunks of a program without stopping to test or debug. I find it easier to stay in flow if I’m not being distracted by these separate tasks. if it’s hard to be confident that what I’m writing is correct, it’s a sign that it may be worth finding a way to express it more clearly.
writing UIs declaratively (e.g. via React)
carefully designing a program’s essential state. (and maintaing a strong distinction between it and other state that’s derivable from it)
naming variables and functions such that future-you (or another programmer) can make an accurate prediction about what it is or does. getting this down well means you can often work without having to stop and traverse your program’s graph a bunch.
in-IDE code linkage (e.g. I click on the use of a funciton and it goes to the function definition)
Some random tips:
It’s definitely worth it to have a top-of-the-line laptop with 8+ GB of RAM. If I were to buy a new laptop, I might even go for 16 GB RAM.
I think it was super worth it to learn Vim. I imagien Emacs is similar if that’s your preference.
Generally the more you use keyboard shortcuts and the less you use the mouse, the faster you are at doing stuff.
I definitely think Zshell is better than bash and barely has any learning curve. Similarly I prefer iTerm 2 over Terminal. And tmux is also a must have.
I spent a lot of time on my dotfiles https://github.com/peterhurford/dotfiles as well as corresponding plugins for shortcuts <https://github.com/robertzk/send.zsh, https://github.com/peterhurford/git-aliases.zsh, https://github.com/peterhurford/git-it-on.zsh>.
I found it awesome to move my trackpad speed to the max for the times when I do have to use the mouse. It took like 20min to get used to but now switching back is unbearably slow.
Probably getting good at writing tests. I find that writing good tests for code is often harder than writing the code itself, since it often ends up requiring you to understand a lot more of the codebase in order to set up the scenarios you care about or mock out relevant external dependencies. Tests are really important– when I decide not to test something, I regret it maybe half the time because it ends up having a bug, or I break it later.
On the practices side of things:
Follow your instinct to be lazy
If something is genuinely annoying about how you’re building something (and/or there’s a bunch of boilerplate), there’s likely a better way.
The fun thing is this is a self-resolving issue. If it’s annoying you it’s probably annoying someone else who has fixed it. If there is no fix, you can fix it for yourself. Following that instinct has led to some solutions and an overall more pleasant coding experience.
Tools:
Symlinks are love, Symlinks are life.
I’ve had much cleaner organization patterns evolve because I can use symlinks as standins for true paths. You can see examples of this in package managers (homebrew is pretty transparent about this) for library support. You can use symlinks to monkey patch other software and can build user environments more cleanly. There are also certain tools and libraries that may make assumptions about paths on your system that aren’t relevant to your case. Symlinks allow you to meet those requirements without altering your personal directory structure.
The mental epiphany of “I don’t know what this library is doing … oh, the source is available, I can look at it myself”. (Which led to “I can fix it myself”!)
Also, tools. I don’t use an IDE, I use vim for everything; but I have a ton of bash aliases and scripts for things like “run tests”, “push to code review”, “get the current release branch and cherry-pick this commit to it”. Automating all the parts of my workflow that I can, so that I can focus my energy on the parts that are interesting and unautomatable.
Pair programming, going to group coding sessions/civic hacking events and online peer reviews. The more collaborative the process the more we can learn and improve from each other. I was excited to see livecoding.tv the other day… Fun seeing people coding, listening to music and chatting/getting feedback about the process. Anything to make coding more accessible, fun and collaborative.
Hi Ben,
I was pointed to your site by Nat and found it very interesting. I have been writing code continuously since 1967 and find that languages are much less important than work habit. II use FORTRAN, Perl and csh and make no apologies for being an early adopter, using FORTRAN for a decade before c was invented and Perl a decade before Python was available.
For me, the hardest thing is keeping context and not forgetting what I am doing in spite of continual interruptions. I do this by five strategies: (1) I hacked the tty manager in linux (and now OSX) to remember a separate command history for each window. I open 20 windows using the ancient Windows Manager fvmw2 and each remember 5,000 commands. Each month I save my histories and have a script that can tells me when and in which window I used any command or fragment thereof (350,000 lines since 2005). (2) I have a journal that is a text file with dated sections. It was started in 1997 and is now 65,000 lines long. (3) I wrote my own locate script that indexes, title, size, date created and date last used of all 5.5 million files on my laptop. I also use spotlight to index some files and have a Windows virtual machine that full text indexes 350,000 emails and 640,000 files. (4) Use reliable hardware that is customized as needed (right now a 2012 MacBook Pro with 16 GM memory and 1 TB SSD and 2 TB HDD). This machine is continuously backed up and always wakes from sleep. (5) I use emacs in server mode and likely never use more than a dozen commands that my fingers remember.