Link
Mind the attention traps
Alan Jacobs, The Homebound Symphony:
Station Eleven had the Traveling Symphony: I’m trying to be the Homebound Symphony. Just one person sitting in my study with a computer on my lap, reading and listening and viewing, and recording and sifting and transmitting – sharing the good, the true, and the beautiful, with added commentary. The initial purpose of this work is to repair, not the whole culture, but just my own attention. On a daily basis I retrain my mind to attend to what is worthy. It is the task of a lifetime, especially in an environment which strives constantly to commandeer my attention, to remove it from my control, to make me a passive consumer of what others wish me to look at or listen to.
Take care to monitor your attention, especially regarding social media. It’s easy to get lost in nostalgia and repetitive feedback loops. Make sure that at least some of your influences – be they people, feeds, or algorithms — encourage a forward-looking, forward-thinking mindset. Otherwise, you risk stagnation, cycling through the same thoughts and experiences.
Little victories amongst the bigger vision
A couple of my favorite Ruby friends mentioned that they’re trying to keep their side projects small. Despite that very practical aspiration, the siren call of larger projects still beckons. We know the pragmatic step is to find the little projects inside the big projects and share/ship those.
And yet…it’s easy to fall back into big projects, forgetting to show progress. So here I am, showing a little bit of progress! 🤞
...
Here's a behind-the-scenes look: I wrote this months ago, when I was trying to get back to consistently blogging. It was my the little push to get the habit started again.
The astute amongst have noticed that I've been somewhat consistent for the past few weeks. But I'm about to jaunt off for a few days of vacation and I didn't want to let my progress reset to zero. So I dug this post back up and here we are. Repurposed for a good purpose.
I'm still here, showing progress. Finding the little victories amongst the bigger vision. Keeping the candle lit, per se. As it turns out, if perfect is the enemy of good, skipping your blogs because you're going on vacation is the enemy of sticking with the habit of blogging. 📈
The systemic sublime makes our world more legible
My new favorite category on Kottke.org is the systemic sublime, wherein our networked, often inscrutable world is made more legible. The connections between ideas and and their instantiations are not always obvious. The history, and often the path dependence, of how we got here make it a little easier to understand our world.
Other fine purveyors of system sublime include Alexis Madrigal, Matt Webb, Tom Armitage, Ribbonfarm, Steven Johnson, and Michael Lewis. My favorite thing about these authors is, they are answering “why?” by connecting the dots between “how”, “who”, and “what”. It’s my favorite kind of thinking!
Bias to small, digestible review requests. When possible, try to break down your large refactor into smaller, easier to reason about changes, which can be reviewed in sequence (or better still, orthogonally). When your review request gets bigger than about 400 lines of code, ask yourself if it can be compartmentalized. If everyone is efficient at reviewing code as it is published, there’s no advantage to batching small changes together, and there are distinct disadvantages. The most dangerous outcome of a large review request is that reviewers are unable to sustain focus over many lines, and the code isn’t reviewed well or at all.
This has made code review of big features way more plausible on my current team. Large work is organized into epic branches which have review branches which are individually reviewed. This makes the final merge and review way more tractable.
Your description should tell the story of your change. It should not be an automated list of commits. Instead, you should talk about why you’re making the change, what problem you’re solving, what code you changed, what classes you introduced, how you tested it. The description should tell the reviewers what specific pieces of the change they should take extra care in reviewing.
This is a good start for a style guide ala git commits!
Fewer changes are faster to deploy than fewer changes
Itamar Turner-Trauring, Incremental results: how to succeed at large software projects:
- Faster feedback...
- Less unnecessary features...
- Less cancellation risk...
- Less deployment risk...
👏 👏 👏 👏 👏 read the whole thing, Itamar’s tale is well told.
Consider: incremental approaches consist of taking a large scope and finding smaller, still-valuable scopes inside of it. Risk is 100% proportional to scope. Time-to-deliver grows as scope grows. Cancellation and deployment risk grow as time-to-deliver grows. It’s not quite math, but it is easy to demonstrate on a whiteboard. In case you happen to need to work with someone who wants large scope and low risk and low time-to-delivery.
If I could imagineer Tomorrowland for a moment
A little bit of fan reflection on Transportation in Tomorrowland and how to revitalize it:
When you visit Disneyland in California, how do you feel when you walk down Main Street, U.S.A. and turn right to enter Tomorrowland? I mostly feel a combination sadness and frustration when I walk through Tomorrowland–primarily due to the misplaced and pathway– clogging Astro Orbiter and the vacant, rotting PeopleMover track. And while fantasy space travel is well represented in Tomorrowland (Buzz Lightyear Astro Blasters, Star Tours, and Space Mountain), any semblance of tangible ways of pondering, dreaming about, and honoring humankind's achievements and the wonders of the future are long gone. It's as if Disneyland, like seemingly so much of the world, gave up on an optimistic view of the future, too.
Personally, I’d copy/paste the Magic Kingdom People Mover over to Disneyland, keep the monorail as-is, bring back the motor boat cruise as some kind of “see the world from a personal-sized yacht” thing, and reimagine Autopia as pure-electric autonymous cars that are integrated with pedestrian, bicycle, and commercial traffic in a way that is less car-centric as our current world. The five second pitch: the future of transportation is global and interconnected.
Computers are coming for more jobs than we think
A great video explainer on how computers and creative destruction are different this time. Why Automation is Different this Time. Hint: we need better ideas than individualism, “markets”, and supply-side economics for this to end well. Via Kottke.
Stored Procedure Modern
The idea behind Facebook’s Relay is to write declarative queries, put them next to the user interaction code that uses them, and compose those queries. It’s a solid idea. But this snippet about Relay Modern made me chuckle:
The teams realized that if the GraphQL queries instead were statically known — that is, they were not altered by runtime conditions — then they could be constructed once during development time and saved on the Facebook servers, and replaced in the mobile app with a tiny identifier. With this approach, the app sends the identifier along with some GraphQL variables, and the Facebook server knows which query to run. No more overhead, massively reduced network traffic, and much faster mobile apps.Relay Modern adopts a similar approach. The Relay compiler extracts colocated GraphQL snippets from across an app, constructs the necessary queries, saves them on the server ahead of time, and outputs artifacts that the Relay runtime uses to fetch those queries and process their results at runtime.
How many meetings did they need before they renamed this from “GraphQL stored procedures” to “Relay Modern”?
(FWIW, I worked on a system that exposed stored procedures through a web service for client-side interaction code. It wasn’t too bad, setting aside the need to hand write SQL and XSLT.)
Jeremy Johnson, It’s time to get a real watch, and an Apple Watch doesn’t count:
...watches are one of the key pieces of jewelry I can sport, and while many have no clue what’s on my wrist, those that do… well do. And they are investments. Usually good purchases will not only last forever (with a little love and care), but go up or retain most of their value over time.
When pal Marcos started talking to me about watches, I realized they checked all the boxes cars do, but at a fraction of the price. If cars check your boxes, look into watches. Jeremy’s intro will get you started without breaking the bank.
Practically applying Clojure
Fourteen Months with Clojure. Dan McKinley on using Clojure to build AWS automation platform Skyliner:
The tricky part isn’t the language so much as it is the slang.
Also, the best and worst part of Clojure:
When the going gets tough, the tough use maps
This is probably better now that specs and schema are popular. Before, when they were mysterious maps full of Very Important State, reading Clojure code (and any kind of Lisp) was pretty challenging.
Make sure you stick around for the joke about covariance and contravariance. Those type theories, hilarious!
You should practice preparatory refactoring
When your project reaches midlife and tasks start taking noticeably longer, that’s the time to refactor. Not to radically decouple your software or erect onerous boundaries. Refactor to prepare the code for the next feature you’re going to build. Ron Jeffries, Refactoring – Not on the backlog!
Simples! We take the next feature that we are asked to build, and instead of detouring around all the weeds and bushes, we take the time to clear a path through some of them. Maybe we detour around others. We improve the code where we work, and ignore the code where we don't have to work. We get a nice clean path for some of our work. Odds are, we'll visit this place again: that's how software development works.
Check out his drawings, telling the story of a project evolving from a clear lawn to one overwhelmed with brush. Once your project is overwhelmed with code slowing you down, don’t burn it down. Jeffries says we should instead use whatever work is next to do enabling refactorings to make the project work happens.
Locality is such a strong force in software. What I’m changing this week I will probably change next week too. Thus, it’s likely that refactoring will help the next bit of project work. Repeat several times and a new golden path emerges through your software.
Don’t reach for a new master plan when the effort to change your software goes up. Pave the cow paths through whatever work you’re doing!
The TTY demystified. Learn you an arcane computing history, terminals, shells, UNIX, and even more arcanery! Terminal emulators are about the most reliable, versatile tools in my not-so-modern computing toolkit. It’s nice to know a little more about how they work, besides “lots of magic ending in -TY”, e.g. teletypes, pseudo-terminals, session groups, etc.
Clinton Dreisbach: A favorite development tool: direnv. I’ve previously used direnv
to manage per-project environment variables. It’s easy to set up and use for this. I highly recommend it! But, I’d never thought of using it to define per-project shell aliases as Clinton does. Smart!
The lesser known vapors and waves
There’s a thing going on in music with all the vapors and chills and waves. I’m not entirely sure what it is, yet. Even after reading this excellent survey of the various vaporwave subgenres, I’m still not sure what it is. But it’s very synth-y, a little sample-y, and very much what you’d expect to hear in a hip, contemporary hotel lobby.
Code that resists
Kellan Elliott-McCrea, on the way towards an understanding of technical debt, catalogs the ways we end up with code that resists our efforts to change it:
Therefore the second common meaning of “technical debt” is the features of the codebase we encounter in our work that make it resist change. Examples of features that can make a codebase resist change include: poor modularization, poor documentation or poor test coverage. Just as easily though an abundance of modularization (and complexity) or an abundance documentation, and tests encoding the now the incorrect old behavior can apply a strong downward pressure on change.
A little discussed and poorly understood design goal for code is disposability. Given change, what design patterns can we follow that allow us to quickly expunge incorrect behavior from our codebase? Interestingly it is a much more tractable metric for measuring as opposed to more popular criteria like “elegance”. (a post for another day)
Put that in your thinker. Does something like Strategy or Adapter let you throw out whole classes when they prove unnecessary? Or is that so only when you luck out and chose the exact right axes of disposability? Does a microservice really let you discard codebases wholesale? Can maps and functions free you from intertwingled state and behavior or does it move the resistance somewhere else?
Grumpy, opinionated answers: possibly! Even more possibly! Meh. Very meh.
The future of programming is design, teaching, and empathy
The Future Programming Manifesto starts with this header:
Inessential complexity is the root of all evil
OK, I’m on board!
We should measure complexity as the cumulative cognitive effort to learn a technology from novice all the way to expert. One simple surrogate measure is the size of the documentation.
Perhaps we could describe the complexity of a technology in “bookshelves”? For example, in my second internship I met a CleearCase administrator whose office bookcase had one shelf devoted to SunOS, one shelf to Oracle, and the final shelf dedicated to ClearCase itself. How many bookcases for Ruby, Rails, JS, CSS, a database, and all the other stuff you need to know to put a CRUD app in your browser (not even deploy it to the web!)
- Maintaining compatibility increases complexity.
- Technical debt increases complexity.
- Most R&D is incremental: it adds features and tools and layers. Simplification requires that we throw things away.
- Computer Science rejects simplification as a result because it is subjective.
- The Curse of Knowledge: experts are blind to the complexity they have laboriously mastered.
- Rewarding programmers for their ability to handle complexity selects for those who love it.
- Our gold-rush economy encourages greed and haste.
A weird thing about programmer is that those that rant endlessly about someone else’s complexity, layers, and haste are almost completely blind to the complexity, layers, and haste they make in an effort to set the world just so.
We should work for end-users disenfranchised by lack of programming expertise. We should concentrate on their modest but ubiquitous needs rather than the high-end specialized problems addressed by most R&D. We should take inspiration from end-user tools like spreadsheets and HyperCard. We should avoid the trap of designing for ourselves.
What if more of programming was accessible as data manipulation (cf. spreadsheets, data files, JSX templates) instead of as logic and behavior (i.e. almost every programming language)?
We are doing Design: using experience and judgement to make complex tradeoffs in order to satisfy qualitative human needs.
This reminds me of Developer Experience. “Developer experience” is a weird word right now, but it’s becoming table stakes for success. It’s a design discipline. It’s considering the form and function of code. It’s the opposite of attempting to learn C ;)
Long story short: we’re gonna need more empathy, more design skills, and more teaching skills to reach the next level of great programming languages and tools.
One model doesn't fit all
There are two kinds of developers in the world:
- those who realize data models aren’t monolithic and use business boundaries to their advantage
- those struggling with monolithic data models
The wolf moves fast...
The Wolf moves fast because he or she is able to avoid the encumbering necessities of a group of people building at scale. This avoidance of most things process related combined with exceptional engineering ability allows them to move at speed which makes them unusually productive. It’s this productivity that the rest of the team can… smell. It’s this scent of pure productivity that allows them to further skirt documentation, meetings, and annual reviews.
See also, The Grinder.
How waterparks became a thing
The Men Who Built the Great American Waterpark, a roaring tale about the fellows who created the notion of a park for water attractions, from Wet and Wild to my personal favorite place on earth, Schlitterbahn. Told as is typical of the slightly nerdy, slightly narrative Grantland form.