In his talk Solving the Right Problems for Engine Programmers Mike Acton’s first segment is about how new programmers are usually incompetent in three fundamental ways: practice, reasonable defaults, and problem solving.
He goes on to say that most programmers do not practice, i.e., they do not take time out of their schedule to practice using the tools (languages, APIs, databases, whatever). I’ve been thinking about this for a while and it seems that a lot of professions have practice, but in the tech industry we don’t, we mostly go with sink or swim.
So my question is: do you have a regular practice? What is it like? Do you have tips and hints and recommendations for others?
My practice routine used to consist of idling on ##c on freenode, looking at questions people were having with regards to C and solving any code problems they come up with. I usually made sure that if I were to send the person the code it was either instructive (in the case of outright rewriting what they wrote) or didn’t completely solve the problem (in the case of questions on how to do something). This meant I could solve problems I would not normally spend my time solving, keep my understanding of C very sharp and provide a high quality of help to people asking in the channel.
This is both brilliant and obvious. Obvious in the sense that helping others helps yourself; it’s a tried and tested method. Brilliant in the way that skill sharing is not something ingrained in the culture.
Don’t get me wrong - there are a lot of places to get help on the internet and that’s a great thing. But you’ll know it’s part of the culture when “productivity” is measured - in part - by the amount that you help other people.
Ex #linux (IRCNet) and #csharp (Freenode) hanger-outer here, learning in the same way. Free time? See an interesting question? Try to solve it. If it seems like it’ll help, post it. The original requestor or others provide more info and you end up with a full picture. A fantastic way to learn.
Did you do this on your own time or as psrt if your job? For the discussion on the industry culture that would make a big difference.
I did this entirely on my own time.
Summarizing how Mike Acton defines practice in the talk:
I don’t meet this definition of practice. I think this definition of practice might be a bit narrow.
I do aggressively explore gaps in my knowledge and then either write notes or code for myself, or I might blog about my findings.
However, the output isn’t necessarily ephemeral or throwaway. The code might be throwaway, but the output becomes part of my notes or on a blog. The code might not even be throwaway, since it may become part of my permanent notes or a blog post.
Is this competitive? No.
Are my permanent notes or blog a project? Possibly.
Does this happen daily? Sometimes.
Does it fit into 30 mins? Sometimes.
I don’t think that “fit in 30 min” is even a good constraint for programming practice?
Edit: Expanding now that I’m on a real computer, not my phone
The kind of skill I want to improve, ergo the kind of skill that I would want to practice, is mostly not 30 min things. How do I create more robust architectures? How do I write more readable code but still keep things flexible and extendable? How do test systems that rely heavily on cloud resources, but still keep tests fast and the coding feedback loop tight? Those are not things that you can go on HackerRank and practice fort 30 min.
Maybe I could use some practice in coding faster, on writing algorithms and datastructures from memory, or solving puzzles with code, but that’s not the stuff that I usually feel lacking in my day to day work. And it also sounds boring as fuck.
The last one is weird, given most of the research on learning suggests that 30-minute chunks are not usually a good idea.
I generally use personal projects to learn new things. If I have a project that isn’t likely to have a lot of users or need long-term support, I’ll use it to try something that I’ve thought I might want to use in real work but haven’t had a chance to learn. This is why all of my personal projects at the moment are using exciting new C++20 features.
Oh, that’s interesting. What does the research suggest? What resources should I check to learn more about this?
I’m interested to see the responses to this one. Deliberately practicing programming isn’t part of my routine now. It might have value if I were still a “new programmer,” but in my case, years of recreational programming have sated any perceivable need for practice.
It takes a lot of effort to come up with a routine that’s more effective than the “sink or swim” approach – effort that could be more meaningfully spent working toward whatever you’re learning programming to do.
Do recreational programming count? I don’t practice anything per se, but I do do a bunch of recreational programming mostly to:
Mostly I mix both of the above, and end up backing myself into dead-ends; the itch gets bored and go away by itself, and I am left with just the experience.
I think recreational programming should be part of the corporate / entreprise / company culture. Doing it only on your free time makes it an underrated practice.
Not sure that this applies. From the talk, the practice is really about doing repeated drills in order to improve a specific skill. Think shooting free throws 30 minutes per day.
For those wondering what “practice” means according to Mike Acton, see the linked talk starting around 13:00.
Based on what Mike Acton says, no, I don’t practice and I don’t think I ever have. Nor do I think it is necessary. It doesn’t sound like a bad thing, mind you. That said, what he describes as practice is the kind of thing I do when solving problems or just doing my daily work.
No, I don’t.
I use new tools, but I pick them up in a relatively disorganized way. The closest thing to practice I do is that I put some common commands and concepts I wanted to remember into Anki. I’m 50-50 on whether that was useful (potentially because of poor choices around the entries I added). I also keep a text file of common issues I’ve run into and how to solve them. I view that habit as definitely positive, but it’s not really practice per se.
If you’re interested in this topic, I appreciated a recent thread by Dan Luu: https://twitter.com/danluu/status/1442945072144678914
Michael Malis has written about recording himself solving issues, and reviewing it later: https://malisper.me/recording-footage-of-myself-investigating-a-performance-issue/.
I used to answer questions on stack overflow, which I think functioned as a form of practice.
My go to for practice with a specific language is https://exercism.org/
For practice with frameworks and other systems, I’ll take the tutorials on their main site and TDD out the solution they provided. Which improves my understanding of the framework, but also skills up my TDD.
Similarly to some other posts, I’ve looked at Stack Overflow questions and determined those solutions which helps solidify my understanding.
I leverage git for all projects I work on. Even if the main code base is managed in SVN. This allows me to start a branch to do a thing and try it out and then scrap it.
I never “practiced” in a traditional sense – instead I build small tools for myself. And sometimes I port things between languages. I think porting is underrated as a way to learn both a language and a problem domain.
I recently remembered I ported a toy make from Kernighan, written in awk, to Python:
https://lobste.rs/s/xpv7ly/learning_reimplementation_make#c_xcsvqo
That helped me learn both awk and Make, since I already knew Python :)
I also made a demo for people of porting JavaScript to C: https://github.com/andychu/javascript-vs-c
If you already know JavaScript, I think you could learn a little C that way. The other point of this was that JavaScript and C are basically the same speed for this toy Mandelbrot problem due to the JIT. You don’t even need WebAssembly.
Programming is a broad topic (language knowledge, tooling, ecosystems, algorithm design, project architecture, etc.), but I’ll focus on knowledge of languages. I don’t have a regular practice besides just writing code as part of work, school, and personal projects.
The way I see it, knowledge of a programming language is much like a spoken language. I read, write, and speak English daily, but I never set aside time for deliberate English practice. Yet by using English daily my skills stay strong (and I pick up new words and concepts on occasion). When writing code in C++, Python, or any other language, using it close to daily is enough for me to maintain or build my skills.
As an anecdote, I once went about two years without programming. My first project after that was in Python. It took a days to remember everything, but my knowledge came back much faster than it took to learn it in the first place.
So at least for me, just writing code while for a project or assignment is enough to build and maintain skills, no set aside practice needed.
Heh, funny you should mention this – I watched that video a few days ago and was thinking about programming practice too recently.
While many programmers (myself included), build side projects to push their abilities, I don’t think many of us practice in quite the way it’s described in Mike Acton’s talk. He recommends that developers practice by solving the same problem every day over the course of a few weeks, throwing away the result at the end of each session. I’ve certainly rewritten the same side projects from scratch over the course of years which I think accomplishes the same goal, albeit with a much slower iteration time (months/years rather than days).
The closest I’ve come to this pure form of practicing is when working on problems for Advent of Code and solving interview questions on Leetcode. Although, I’m not sure the AoC problems count because I only attempted to solve most of them once (rather than repeatedly solving the problem and making incremental improvements each time). Also, most of them didn’t really push my to learn something new.
That leaves Leetcode problems. My experience practicing them definitely helped me to solve the same types of “algorithmic” problems in Python more quickly. It also helped me to become very familiar with the Python syntax and stdlib, and forced me to analyze boundary cases to prevent off-by-one errors and the like (e.g. knowing the second argument to range() is exclusive, or that in the expression
a[0:x]
,x
can be greater than the length of the list and won’t throw an index exception, etc). This knowledge has only been marginally useful outside of interviews, unfortunately. Most of the code I write on the job isn’t that algorithmic.I can’t find the link now, but I remember reading somewhere that Joe Armstrong did something similar when working on a new problem. He’d create an empty directory, create a file named
1.erl
, and solve the problem as directly as possible. Then he’d pop open a new file named2.erl
and solve the same problem again. After iterating a few more times, he’d have a clean solution and a much deeper understanding of the problem than he started out with.Personally, I like building projects, and I don’t like this form of ephemeral practice all that much[1]. I don’t think forcing myself to practice in this manner is as valuable as building side projects since I find that more fun (and motivating). However, I definitely can see the value in doing it if I wanted to get faster/better at implementing some specific feature. For instance, I could practice writing the code to build an orbiting camera for a mesh viewer since I’m so slow with matrix math and graphics APIs. I do wish Mike Acton would have provided more examples of useful things to practice in that talk…
The rest of that talk is great too, though – particularly his rant about how developers tend to try and generalize a the problem and write a “compiler” so the user can solve the problem (and the solution itself becomes a problem in and of itself), rather than just solving the stinking problem to begin with. I’ve definitely been guilty of that myself :P
[1]: I’m a guitarist and the same applies there unfortunately – I really enjoy songwriting, recording, and producing, but don’t spend nearly enough time practicing my technical playing ability anymore. I used to, and continue to rely on the skills I developed a few years ago, but I’ve certainly noticed a slight degrade my skills recently.
I’ve been learning Rust by more or less solving the same two problems (a simple JSON-RPC-ish API and a basic hex grid game board/UI) every month or so using a new set of patterns, libraries, etc. I don’t port the old code over; rather, I use it as a reference and try to build the new version in a way that feels idiomatic given the new dependencies and my slowly-growing knowledge of the language.
It’s probably more “practice” than I’ve given anything since I stopped playing music 20 years ago, and scratches a similar itch. (I wrote software professionally for a decade or so before getting nerfed into management, where I’ve spent the last 10 years of my working life.)
I don’t quite practice in this way, but I do explore new programming ideas, and revisit old ones often, and port between languages. I also explore the edges of what I know how to do in the tools I use quite often.
I’ve written my idea wiki sever in Erlang, Nim , and then Elixir. I’ve written a punch clock time tracking tool in Nim, and then wrote a directory scanning tool in Janet to do the same, and then wrote a much more sophisticated time tracker in Janet later.
I wrote a polling file change watcher in Janet, and then turned around and rewrote in PowerShell to allow for re-using web sessions in API tests.
I’ve revisited dialogue-driven cutscenes twice in game jams, and will more in the future.
I’ve written multiple RPN evaluators, every thing from Stack of Strings type things in JS, to the same in Nim, to PISC.
My ADHD brain makes daily practice as suggested by Acton a bit harder to pull off, but he’s not the only person to suggest it, Noah Gibbs (aka @codfolio on Twitter) also strongly believes in this sort of practice, and even wrote a book about it, Mastering Software Technique.
For me, I just set an extremely low bar for the code I write on the side, so I can be experimental, and I write a lot of experimental code in LinqPad or in a REPL when I’m working in solving a problem at work, especially if it involves APIs or munging data.
But, I also have a well developed sense of how to go from messy code to code with more structure, and how to try to aim that structure in different directions.
Also, I do believe that many, if not most, programmers undervalue the development of a certain sort of “muscle memory” around many of the subtasks in programming
After I started working I find that my leisure programming has dwindled, including practice (my definition). Using the definition in this talk it sounds like I never did practice, there is always a goal artifact, and once that has been produced the task is done, even if it’s just another checkmark-goldstar-proceed-to-next-level on some sort of programming challenge site.
I find in my professional life what is difficult is not directly related to the writing of the code, how to write the code, what language constructs to use etc (but this might be due to my domain), but how to deal with requirements that may have holes, may lead to absurd edge-cases, may clash with legacy code; where supporting some legacy behaviour is the requirement, but the legacy implementation does not really follow the associated documentation or requirements. The closest I get to the code when dealing with these parts of an implementation task is figuring out how to make the smallest permutation to a legacy codebase that will support the newfangled sweet thing, determining if it’s at al feasible or if rewriting [part of] the whole thing is the way to go.
I’m not sure that is something that can be practiced in isolation outside of an actual task, on my own, and if it is it’s probably not something I would want to spend time on without getting paid for it.
I don’t think that Acton’s vision of practice is the only valid one, though it does have a lot to teach folks.
For me, my practice is currently a lot more diffuse, but I definitely still am a student of programming, and of code.
I don’t meet Acton’s definition of “practice”, but I really like “recreational programming” and I have a ton of mini-projects on GitHub, where I try out ideas I have, or implement algorithms and data structures I learn about or try new tools, languages, and libraries.
It’s an interesting way to think about it, though, and I wonder what effect adding more practice-oriented structure would have?
I would love to practice, but I’m usually exhausted by work, so I try not to think about code in my free time. I realize this will make me a worse programmer over time, relative to others. After all, all the best programmers I know code a lot outside of work.
I disagree, I think striving for balance in your life and making time for family, friends, relationships, life admin, and non-technical hobbies benefits your health and ultimately makes you a balanced individual. Being balanced makes you a better human being.
Yes, it makes your more well-rounded. But someone who programs for more hours, even without much intentionality, is going to be a better programmer over time.
Yes, all the time. I spend at least a couple of hours per week tinkering with something. I ran my own Jenkins to tinker with automation. I fired up a postgres database to try storing some data in it. I’ve built systems to download and analyze data automatically. I blow away the OS on a machine and install it from scratch now and then.
Thank goodness I do, too. This actually came in very handy when I started tinkering with Selenium for web UI automation recently. A few weeks later we needed to automate something in a web-based application that wasn’t exposed via the API, and Selenium gave me a quick-n-dirty option to get it done!
I sometimes try to practice using tasks on Project Euler. I pick different programming languages for different tasks, sometimes I re-do a task in a different programming language only to see if there are any constructs in that language that will help with my already found solution.
Also sometimes I install some new software and I learn how it works, not because I need it now, but because I may need it in the future, and I’m interested in how it works. Sometimes I install several applications related to the same domain and I compare what are the approaches used by different software to solve one particular problem.
Does that count as practicing?
I can’t say I practice each day, but I do read a lot but that isn’t practice. When I have glimpses of what this would look like, it is when:
htop
ortmux
. You will learn something.