On the night of December 31st of last year, I wrote "New Ambitions for a New Year," a blog post outlining a number of self-imposed goals for 2019. The words I ended on were: "[t]oo ambitious? Well, I guess we'll find out in 365 days when I write another post like this." Indeed, what you're reading right now is something I expected to author much later, but enough has changed in the past three months that I feel it's appropriate to put out an addendum now. The post's original text follows.
As we draw on the final hours of 2018, the only words I feel appropriate are: "wait, it's really January tomorrow?" The past twelve months have felt deceivingly short despite everything that's happened in that span of time. I had a number of rough job interviews, met Richard Stallman in person, installed Gentoo, became a legal adult, graduated high school, and finished my first semester of university, all in what seemed to me like just a few weeks.
"Productive" is how I'd characterize the year, but I'm having a hard time rationalizing why it is that I feel that way. Yes, I reached two major milestones in my education, but I still don't know what to make of everything else I did. I'd probably feel better about my accomplishments if I had a goal and a means of assessing whether or not I achieved it, but alas, I didn't set any out of the same cynicism that drives me to point out resolutioners contributing to the January gympocalypse. I'd like to mend that cynicism for 2019, though. One year really isn't a bad span of time for setting goals – it's long enough that you can be ambitious in your planning, but short enough that there's pressure to continue making progress throughout the year.
So, I've come up with some goals for myself, and I've decided to write about them to impose some level of accountability.
This year, I managed to put out seven articles. Last year saw four, and the year before saw one. A linear regression suggests that I'll be putting out ten this year.
I kid. As tempting as it is to make "write more frequently" one of my goals, my focus will be on quality over quantity. In 2019, I plan to:
- Read through all of my past posts, drafts, and favorite articles, taking notes on how they're written, and synthesizing a writing style that can be thoroughly described on paper. If you've read my earlier writing, I anticipate that you've noticed significant variance in the presentation of each piece. It's time for me to identify the aspects of style that work, and find a way to consistently incorporate those aspects into my future writing.
- In a similar fashion, develop a consistent method for doing research and managing sources throughout the writing process. I believe my technical writing will benefit if I make a habit of perusing the existing corpus of research prior to putting words down on paper.
- Expand my writing endeavors to Wikipedia. I've collected a number of sources for expanding Wikipedia stubs, and my goal is to turn every entry on that list into a series of edits. Ideally, I'll go beyond that, but given the preceding goals, I think that it makes sense to start small. Writing for Wikipedia will expose me to critique from more experienced writers, and give me experience writing in an encyclopedic style.
No hard article count goals this year, because again, quality over quantity. If I'm forcing myself to write to fill a quota, my heart won't be in it.
Contributing to Free Software
I'd like to migrate all of the projects I maintain to sr.ht, but I'll be keeping my GitHub account for sending pull requests to projects that live on there.
Originally, I had a list of projects that I wanted to contribute to in the new year, but I haven't read a single line of code from any of the entries on that list and there's a good chance that I'll have second thoughts about contributing following the first perusals, so I've decided that a more reasonable goal is to become a regular contributor to at least one project. By "regular contributor," I mean gaining enough of a presence that people are coming to me to ask questions about the code.
I have tried, and failed, numerous times to get through Hal Abelson and Gerald Sussman's Structure and Interpretation of Computer Programs. Now that I'm more mature in terms of rigor, I've decided to finally buckle down to make my way through the text and all of its exercises. It's a fat 657 page book, but I'm more than capable, and I have an entire year to do it.
My more lighthearted goal is to put out at least one demo on either the Super Nintendo or the Nintendo DS. I've always wanted to program for a platform where I'm constrained by the limitations of the hardware.
Capture-the-flag used to be a more significant hobby of mine; I mostly dropped off the scene when I graduated high school, but I'd like to get back into it. In a similar vein to my SICP goal, I'm aiming to finally get through a book that I've failed to finish in the past, Reverse Engineering for Beginners, and complete at least 50 of its exercises. 50 is a about one per week, which I think is reasonable.
I've tried several times in the past to learn "electronics", and never progressed beyond the laws of Ohm and Joule. I think the issue was that I didn't know what I wanted to learn; I set out to study "electronics," which wasn't specific enough. This time, I'll be more diligent in finding curriculum that's relevant to me. I want to learn to read boards and gain the knowledge necessary to repair my Commodore 64, so my focus will be on the design of electronic circuits. I'll achieve this is by going through the coursework for MIT's 6.002: "Circuits and Electronics". It's a course I wanted to go through when I was a sophomore in high school, but at the time, I was discouraged by the list of prerequisites in the syllabus.
Another goal of mine is to join an amateur radio club. I've already got two in mind: SDFARC and the one that runs the local 2-meter repeater I frequent. My thought is that joining one will give me an opportunity to find an Elmer whose brain I can pick about RF electronics.
One of my favorite courses in high school was Mandarin Chinese. I took it for four years, and while I wanted to continue studying it at university, I sadly couldn't fit any classes into my schedule. The four years of study left me with a grasp of the language's fundamentals, however, and I think that I could reasonably continue to learn the language on my own accords. Throughout the year, I plan to:
- Learn the vocabulary on Wiktionary's list of the 1000 most frequently used words in Mandarin. I already know a number of words on the list from my four years of study, and learning the rest should give me a good base for reading from newspaper articles and books. I plan to learn the words' definitions and pronunciations through spaced repetition, and I'll handwrite the character every time I review the card for it. Although the ability to handwrite characters isn't a specific goal of mine, I've found that it helps me in learning to recognize the characters.
- Read C程序设计语言. I have a translated copy of Kernighan and Ritchie from when I went to 王府井, so that should be reading that's both engaging and full of the kind of vocabulary that I'm interested in learning.
- Make friends with at least one of the international student in my dorm. I'd feel bad conscripting someone solely for the purpose of helping me learn Mandarin, but I figure that if I befriend someone whose native tongue is Mandarin and spit a bunch of broken Chinese at them, they'll be inclined to correct me (through laughter, perhaps).
To recap, my goals this year are:
- Move my software projects to sr.ht.
- Join an amateur radio club.
- Make friends with at least one of the international students in my dorm.
- Synthesize a consistent writing style and document it.
- Synthesize a method for performing research and document it.
- Turn my list of articles into a series of edits to Wikipedia stubs.
- Learn the 1000 most frequently used words in Mandarin Chinese.
- Read C程序设计语言.
- Read SICP and complete all of its exercises.
- Read RE4B and compete at least 50 of its exercises.
- Complete the coursework for 6.002.
- Put out at least one demo on either the Super Nintendo or the Nintendo DS.
- Become a regular contributor to at least one free software project.
Too ambitious? Well, I guess we'll find out in 365 days when I write another post like this.
As alluded to in the introduction, I've come to understand that achieving every goal on that list within the span of a year is impossible. Well, at least for a full-time university student. Balancing a course load of 19 credits with undergraduate research and a social life leaves me with little more than a few hours on the weekends to dedicate to those tasks. As such, I'm reevaluating and redefining my goals for 2019.
What's more, some of the things on that list no longer even interest me. Why invest significant time into something I know I won't find fulfilling? Take the plan for continuing my study of Mandarin Chinese as an example: bilingualism seems like it might be useful, but I have no realistic use for the skill, and I was really dreading the daily practice I was putting in for the first few weeks of the year.
The other issue that's come up is a loss of motivation for some of the tasks that, unlike continuing my study of Mandarin, I would find fulfilling. To remedy this, I've decided to associate small integrative projects with each of the goals I intend on keeping. This move is inspired by the points made in Norvig's Teach Yourself Programming in Ten Years, which I had read several years ago but was reminded of after a recent perusal of the introduction to Functional Programming in OCaml. I'd specifically like to quote a few things he lists in his "recipe for programming success":
- Get interested in programming, and do some because it is fun. Make sure that it keeps being enough fun so that you will be willing to put in your ten years/10,000 hours.
- Program. The best kind of learning is learning by doing. To put it more technically, "the maximal level of performance for individuals in a given domain is not attained automatically as a function of extended experience, but the level of performance can be increased even by highly experienced individuals as a result of deliberate efforts to improve." (p. 366) and "the most effective learning requires a well-defined task with an appropriate difficulty level for the particular individual, informative feedback, and opportunities for repetition and corrections of errors." (p. 20-21) The book Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life is an interesting reference for this viewpoint.
- Talk with other programmers; read other programs. This is more important than any book or training course.
- Work on projects with other programmers. Be the best programmer on some projects; be the worst on some others. When you're the best, you get to test your abilities to lead a project, and to inspire others with your vision. When you're the worst, you learn what the masters do, and you learn what they don't like to do (because they make you do it for them).
- Work on projects after other programmers. Understand a program written by someone else. See what it takes to understand and fix it when the original programmers are not around. Think about how to design your programs to make it easier for those who will maintain them after you.
Working towards a project is largely conducive of these. It will ensure that I'm having fun, that I'm learning by doing, and that I'm speaking with those who have expertise. So, here's my updated list of goals for 2019, paired with the projects I've come up with:
- Complete the coursework for MIT's 6.002.
- Troubleshoot my Commodore 64 and restore it to a working state.
- Read chapters 1-4 of Structure and Interpretation of Computer Programs and
complete all of their exercises.
- Implement a ray-tracer in Scheme.
- Compete 50 of the exercises in Reverse Engineering for Beginners.
- Write another game hacking post.
- Synthesize a consistent writing style and document it.
- Write another game hacking post.
- Synthesize a method for performing research and document it.
- Adopt the "Heap feng shui" and "JIT spraying" pages on Wikipedia.
Although this is still an ambitious list, I think I can reasonably achieve all of these by 2020. I think the more important point, however, is that I've effectively reduced my original ragtag list of last-minute New Year's Eve thoughts into a clear plan for personal growth. Completing the coursework for 6.002 will enable me to design and reverse engineer circuits. Completing Structure and Interpretation of Computer Programs will teach me to approach problems with a functional programming mindset. Working through the exercises from Reverse Engineering for Beginners will give me a repertoire of patterns for going forward in capture-the-flag and any projects I take on in the future that may involve reverse engineering. Developing a consistent writing style will strengthen my ability to communicate knowledge, and developing a consistent method for performing research will encourage me to exercise that skill of communicating knowledge.
During my initial reflection, I thought that troubleshooting the C64 would make for a poor choice of project, as there's the possibility that I'd start troubleshooting and soon realize that it's borked beyond repair. One thought was to instead follow the instructions outlined in Steve Ciarcia's Build Your Own Z80 Computer, but after looking through the book, I realized that it would be both expensive and probably very difficult to complete due to the age of the components used.1 I also thought to follow Ben Eater's instructions for building an 8-bit computer from scratch, but that also has the issue of price. Ultimately, I decided to go with my original plan to fix the C64. Even if I can't repair the C64, I have a broken VIC-20 I can fall back on, and I think I'd learn more in the domain of reverse engineering circuits than I would following the instructions that come with some homebrew computer kit.
My definition of success for the goal of reading Structure and Interpretation of Computer Programs changed slightly to omit the fifth chapter. I still plan to read it, just not this year. My reasoning comes mainly from skimming ahead to get an idea for an integrative project and seeing exercise 5.51. It'd just be… well, a lot. Why a ray-tracer? It's short, sweet, utilitarian, and would probably be both pleasant and eye-opening to implement in a functional style.
I'll still be working through the exercises in Reverse Engineering for Beginners, but I will not be reading the book in it's entirety. After going through the first few chapters, I've developed the opinion that the book makes for incredible reference material, but that a page-by-page reading wouldn't be valuable for someone with prior experience in reverse engineering. I'll still be skimming a subset of the book2, but I don't want promise to myself that I'll finish those chapters by the end of this year.
One last thing to note – I've omitted the goal about moving all my software projects to sr.ht, as I've succeeded in doing that.