Being a voracious reader, one thing that helps bring the mountain of things I want to read down to something manageable is being able to read things faster. Reading faster itself probably hurts comprehension and digestion of core concepts, but getting digested content from others who have already read the main body of work can drastically reduce the amount of fluff you'll have to wade through yourself. If you've ever read a book review that basically told you everything you needed to know before you've read the book, you'll know what I'm talking about.
I've personally felt this way a lot towards reviews and have found it invaluable. As such, I feel it's necessary for me to pay this back. It's not worthwhile giving rundowns for everything I've read so the purpose of this article is to focus on the things I've found fascinating. This is by no means a comprehensive list and you'll probably find the details per body of work a tad thin as time has waned on since I've read them. However, I do wish to make this more of a regular habit and, in the end, hopefully I can at least express the delight I've had getting through some of these wonderful wading pools of words.
This had so many fantastic insights into programming in the large as well as the small for some of my heroes as well as some people I had never heard of before. Of particular note was the recurring question Peter Seibel kept bringing up: "How do you read code?". In fact, Seibel even did a follow-up blog post on the subject, but my particular take was the specifics that people actually replied with. In fact, the subject matter drove me to write an article about reading code I dubbed 'Reading Code is Decoding'
One other thing I thought fascinating was that one of the leaders of the Haskell language, Simon Peyton Jones, had feelings towards types as proof systems that were less intense as I had originally assumed. In fact, SPJ repeatedly mentions that the idea is about confidence and not about mathematical fact.
Lastly, guys like Brad Fitzpatrick and Jamie Zawinski 'got things done', but they also had a lot of sensibility towards quality instead of simply being 'duct tape programmers'. In my mind, the book does a phenomenal job of showing how several people can think of simplicity from different angles, whether that's avoiding the barbarism of C++ in the face of Netscape's pre-existing C codebase, avoiding unnecessary enterprise software in exchange for possibly less-than-ideal open-source solutions to keep Live Journal up and running, or sussing out obtuse assembly language for an unknown system by mathematically dissecting hunks of code.
Soft skills are hard, and we'll see in a few other reviews that they are even harder to write about and absolutely harder to put into practice properly! But that still doesn't mean people can't try. Things of note:
You will sometimes need to do hard things and tell people hard news, but it's better you do that than try to pretend everything is amazing. In other words, It's better to be 'kind' (honest but considerate) than simply 'nice' (always accommodating)
As you may find yourself with more managerial duties, you're ability to bridge the gap between technical and non-technical members of the business increases; this can be with metrics and even how you handle explaining or using alternative jargon
A healthy codebase is an active one, but the rate of change needs to be kept in check with the rate of errors. There is a subtle hint here about developing a devops culture so that people are aware of how they can best help ship software and know if they are within a predefined error budget. If you impede the error budget, it's time to start focusing more on fixing things, which means having flexible scheduling percentages.
Learning is the most vital aspect of a business and orienting it's processes around it is pivotal in it's success
Having technical chops before you wind up in any managerial capacity is crucial but it's also important to know that things like leadership and empathy takes just as much effort to refine and perfect
I feel like a good follow up to this was reading John Allspaw's article On Being a Senior Engineer. In it, Allspaw hits on several soft skills that 'senior' software engineers absolutely must uphold on a day to day basis, and I really don't see them being that different from soft skills that others should be upholding as well as they increase in seniority.
Choose Boring Tech, Run Less Software, and [You Need a Novelty
I mention these three articles in tandem because they were thoughts I had faintly felt being in various organisations but could not pinpoint with words quite as well as these three articles do. The core ideas are:
You don't always need to map every problem to an ideal solution, in fact, doing so is problematic because you will wind up with too much tech to maintain, and maintenance cost must weight in considering adoption
Every new piece of tech you acquire into your stack means more things people need to know about and the more people need to know means the less they can be experts.
Choosing or building swanky libraries, technology, and services may be exhilarating but it's also problematic for the above reasons. Having a 'novelty budget' can help prevent 'fancy tech creep' into the codebase and infrastructure. In fact, it may help to run as many crazy projects 'on the side' (i.e. outside of work) as possible to help reduce the urge of introducing shiny-new-things
I kept going back to these articles at least every month or two; they serve as a basis of what I think is productive coding: write boring code that fits in your head, is heavily tested, focuses on some clear specification (the proper abstraction), and satisfies "small is beautiful/less is more". I can't imagine that being the end of the proper characteristics and that list keeps morphing as I keep coding, but it seems sensible enough to mention those characteristics in relation to these posts.
For trust to cultivate between members working together to build impossible programs and systems you need respect and you can't build respect until you have empathy for others. You don't need to feel the same thing they feel, per se, but compassion itself is, in my mind and shaped from the sentiments in the book, the difficult but extremely rewarding practice of cultivating concern for others, their suffering and feelings.
In the book, Armstrong equips us with a particular process of better developing empathy for others via religious, sociological, and psychological references. Since this is a heavy process-oriented book, I can't simply give a quick tl;dr, but I do want to recommend this book heavily. It and How to Talk so Kids Will Listen and Listen so Kids Will Talk are both fantastic resources on this subject, although I've read the latter a number of years before this post.
The Morning Paper is probably the best resource for mind blowing information on the internet for software engineers, and I could ramble off many articles that absolutely twisted my brain this year. If you don't have a subscription to the The Morning Paper, you need to go subscribe this instance! Despite it not being the most mind-bending of articles this year, I wanted to point out this particular piece and associated paper because it's such a "oh of course" kind of moment.
The gist? Do a fast search on the JSON payload before transforming it into it's in-memory representation.
Daniel Lemire is a performance and database nut (and so I'm easily a fan). I wanted to include this since I had also included the JSON parsing related paper from The Morning Paper. In this short article, Daniel explores a few industrial grade parser implementations and tries to get at how many cycles it would take to parse per byte, eventually coming to the closing line of:
So you should expect to spend 2 or 3 seconds parsing one gigabyte of JSON data.
I am personally a fan of "Latency Numbers Every Programmer Should Know" and I think things like this are actually handy, back pocket facts that ease estimation, s.t. if you find you're parsing a gigabyte of JSON and it's taking orders of magnitude more than this, you can probably know there are gains to be made, and also know that there might be a happy limit for optimisation.
I have a number female software engineer role models; Julia Evans, Jessie Frazelle, and Charity Majors, to name a few. Charity's kick is on empowering devs to be both coding and operations gurus by empowering them with the superpower of observability. This article by Charity also goes into some core things about operational concerns that are "everyone's problems". The hot take is that devs should be able to take code from cradle to grave; ideation into production which entails all the messy debugging and reversals after Things Go Wrong. The aim is to make everyone a software owner rather than a mere occasional participant.
It may also get the reward for the best work memes of 2018.
Bryan sums this up nicely in the beginning, I'll add my takeaways for each bit.
Aptitude: can the person actually code?
Education: have they persevered through boring lectures and stress?
Motivation: are you driven to write code everyday or is it Just Another Job?
Values, per the doc itself:
One observation is that one's values -- and the adherence or divergence from those values -- will often be reflected in happiness and satisfaction with work. When work strongly reflects one's values, one is much more likely to find it satisfying; when values are compromised (even if for a good reason), work is likely be unsatisfying.
- Integrity: The usual verification that people are who they say they are and not actually crazy, serial axe murders or simply bullshit artists.
You have legacy technology and you wish it would just go away, but how are you going to euthanize it? You could write a new system and hide the other one in the corner, perhaps? But you end up realising that your business relies quite heavily to this chunk of code and that it's actually grown into such a mess you can't fathom now moving away from it entirely and now need to run two things; this is a fairly common problem and I think the gist of this article was spot on: if you want to deprecate A, you need to be focused and clear about how B is going to entirely replace it's functionality to the point where it can be politely deleted out of existence, and you need to make this a common practice as an engineering team as every piece of code you write is legacy the moment you write it. Code rots, and, as such, that shiny new piece of tech you've just built will one day need a successor.
In general the process is the same for any piece of software: do upfront planning with documentation and good old fashioned thinking, get people on board, don't be the machine and automate as much of the migration as possible, help track the actual shift away from the older platform, and finally, don't forget to celebrate your achievements! That last one is huge because if you don't make migrations a big deal, people won't see the value in it!
I'm actually quite surprised that this book devolved into a description of a particular process, but I think it's a worthy ally in the fight to cut the fat out of one's prose (the emphasis is in a workplace setting). Two major things of note I took from this book were:
Be short and to the point but scrutinize your use of data.
It's incredibly useful to get out 'fat outlines' of work before you start obsessing on details and get lost in the subsequent worrying. I write like this now in general: large bulk of content upfront and several passes of refinement afterwards.
The 'iron imperative': "Don't waste the readers time"
That last point kept having me think about the book Don't Make Me Think where the crux of design should be about alleviating cognitive load on the user of the interface. It's a powerful phrase to have handy when needing to point out really lengthy bits of code, comments, or documentation, as well as general communiques.
This book was monumental in getting me comfortable with the idea of doing rough groundwork upfront. In fact, some people describe this as the 'paeto principle' where 'eighty percent of the work comes from twenty percent of the effort'. In my mind I'm sure Pareto never intended this to be about a specific ratio but rather about how a small portion of input winds up relating to a large portion of the output. I actually found no better succinct description of the book except at the start (the rest is still worth the read):
The argument of this book is that we often succumb to the temptation of a tidy-minded approach when we would be better served by embracing a degree of mess.
I've not really read a specific programming-language book in awhile, but I love systems programming and Programming rust (along with several other rust books) focus heavily on the subject; whether it's talking about error handling, rough edges with Unicode, or even how different languages handle assignment in order to explain the borrow checker and moves, I was constantly enthralled to pick this book up despite it being close to six-hundred pages. It's gained the classic 'dirty and crushed pages' aesthetic and it'll probably gain a bit more as I keep trying to double down on rust.
I can't recommend this book enough. I actually finished reading this near the end of 2017, but I love it so much that I wanted to write about it here. I personally don't know of any other book that handles the fundamentals of database internals (along with many modern improvements), database design, clusters, nodes, schema encodings, discussions around guarantees (CAP, ACID) and what are valid and invalid points, consensus in distributed systems, and even modern data processing patterns all while in the context of proposing a credo that data-intensive applications should uphold, in such an elegant and ultimately fun way. I still read through the book for knowledge I may have passed up or forgotten so it's a fantastic resource to have on my shelf.
It's also dawned on me that data processing is programming, and knowing more and more about data and how to handle it is enlightening and empowering.
"SICP" by Abelson & Sussman should be read continuously, ~2 pages a day, returning to page 1 every year. Ditto "Thinking Forth" by Leo Brodie, tho' only ~1 page a day. The former teaches how to think, the latter how to engineer. Both are in unpopular languages, on purpose.
and having read most of the SICP, even watching the entire lecture series, but never having heard of Thinking Forth (but having heard of the language), I was intrigued to hear of a book put on the same page as the SICP! I am actually, also, cheating here as I've read only half of it, but so far it's definitely a different way of looking at software construction in the same vein that the SICP went to lengths to describe.
The heaviest emphasis made so far in the book that I love seems drawn between Domain Driven Design and traditional functional programming: words are vital to how we code, the meaning they carry as well as their surrounding semantics; we group words into lexicons which we can call 'components', and with 'components' we get all the general benefits we get from composition. There is some forth specific information nestled between, but Beckman is wise in a followup tweet, saying:
If SICP were in, say, (popular) Python instead of (unpopular) Scheme, people might be distracted by the Python and miss the thinking. Ditto if "Thinking Forth" were in (popular) Java instead of (unpopular) Forth, people might miss the deeper points about software engineering.
I'm excited to finish it in January, in tandem with Thinking in Systems: A Primer, which I've started just last week and has so far been an amazing way of perceiving the structure of various systems from a proper, abstracted point of view.
I originally thought a format involving simple review styled blurbs might be handy, but it's kind of nice having not thought about some of these various texts for a bit to really see what would stick. I hope this has been somewhat useful or fun!