Adam Keys is Thinking
About Newsletter Now Archive Search
  • Rails generators are underrated

    Every experienced Rails developer should pick up Garrett Dimon’s Frictionless Generators. Generators are an often overlooked piece of the Rails puzzle. The book shines a light on getting the most out of generators in your Rails projects. It’s an amazing-looking digital object too, the illustrations are great.

    (Before I go further, it’s worth noting that Garrett Dimon sent me a review copy, acted on my feedback, and is generally a pal.)

    You should customize generators and write your own

    Conventions, in the form of assumptions that are woven into the framework’s code but also exist as a contract of sorts, are essential to Rails. Following those conventions would not work well if creating a new model, resource, etc. wasn’t made easy and consistent without our friends rails generate resource/model/etc. These generators have been present in Rails since the beginning. I’ve used them hundreds of times and thought nothing of it.

    A few years ago, I realized that generators had become a public API in Rails and that re-use was encouraged. The guide is a good start. I was able to knock out a simple generator for a novel, but conventional, part of our application. In the process, I realized a couple of things.

    No one likes boilerplate and tedium. Generators automate the tedium of boilerplate. This is particularly helpful to less experienced developers, who are likely a bit overwhelmed with trying to comprehend decades of Rails evolution and legacy code (from their perspective) quickly.

    Rails developers are under-utilizing this leverage. Every system that makes it past a few thousand lines of code (or several months in use) develops bespoke conventions. These are easier to follow if you can reduce the mental burden to “when you add a new thingy, run rails g thingy”. Added bonus: starting new conceptual pieces in your app from generators encourages consistency, itself an under-appreciated sustaining element in long-lived Rails applications.

    Luckily, someone was thinking the same thing I was…

    Garrett knows more about generators than anyone I know

    The Rails guides for generators are okay. They whet the curiosity and appetite. But, they aren’t particularly deep. When I first tinkered with generators, I mostly learned by reading the code for rails generate model/resource/etc.

    Frictionless Generators does not require one to jump right into reading code. It opens with ideas on the possibilities of developing with custom generators. Then, it moves onto the practicalities of writing one’s own generator and crafting a good developer experience. From there, it’s down the rabbit hole: learning about the APIs for defining generators, implementing the file-creation logic therein, writing help and documentation for them, generating files from templates, and customizing the built-in Rails generators.

    Garrett goes into as much depth on generators as any other technical author I know, on any topic. Did you know you can make HTTP requests and use their responses in generators? I did not, but Garrett does! Did you know that generators apply the same kind of “oh, yeah, that’s common sense” convention for copying files from generators into applications? I did not, but Garrett does! I don’t think I’d use all these ideas on every generator, but I like the idea that I can return to Frictionless Generators should I have an idea and wonder how the existing, low-friction APIs can help me.

    Further, Garrett offers frequent insights into the developer experience and leverage of building generators. On building generators for “fingertip feeling” so developers can easily (and frequently!) use them:

    I like to aim for no more than one value argument and one collection argument to keep generators easier to use. Everything else becomes an option.

    On approaching generators as high-leverage side-quests:

    Remember that the ease of use is generally inversely proportional to the length of your documentation. Assistance first. Brevity second. Content third. Or, be helpful first, concise second, and thorough third. That said, there are a few other categories of information that can be helpful.


    For me, a good technical book balances presentation of technical information, the right amount of detail, and wisdom on how to apply the two in practical ways. Garrett succeeds at striking that balance while keeping things moving and easy to follow.

    In short, recommended! Rails generators are underrated, whether you’re aware of their existence or not. Smart teams are customizing generators and writing their own bespoke generators. There’s a book on this now, which you should check out if any of this resonated.

    → 5:55 PM, Mar 20
  • “Yes, and” despite pessimistic engineering intuitions

    As engineers, we often face the consequences of shallow ideas embraced exuberantly. Despite those experiences, we should try to solve future problems instead of re-litigating problems-past.

    Engineers put too much value on their ability to spot flaws in ideas. It’s only worth something in certain situations.

    — Thorsten Ball, 63 Unpopular Opinions

    Don’t be edge-case Eddie, wont-scale Walter, legacy code Lonnie, or reasons Reggie. At least try to think around those issues and solve the problem.

    This is very much a note to my previous self(s).

    Pay attention to intuitive negative emotion…If you’ve been asked for quick estimates a bunch, you might have noticed that sometimes the request triggers negative emotions: fear, anxiety, confusion, etc. You get that sinking feeling in the pit of your stomach. “Oh crap”, you think, “this is not going to be easy.” For me (and most experienced software engineers), there are certain kinds of projects that trigger this feeling. We’re still pattern matching, but now we’re noticing a certain kind of project that resists estimation, or a kind of project that is likely to go poorly.

    – Jacob Kaplan-Moss, The art of the SWAG

    Jacob recommends noting how intuition and emotion are natural and not entirely negative influences on the process of evaluating ideas. The trick, he says, is to pause and switch to deeply thinking through the idea (or estimate) you’re presented with.

    This, again, is very much a note to my previous self(s).

    Now, if you’ll excuse me, I need to get back to brainstorming and estimating this time machine, so I can deliver this advice to my former self.

    → 12:37 PM, Feb 29
  • Building software is great

    …even if some days working in corporations or under unwanted pressure makes it considerably less fun.

    I also just don’t especially want to stop thinking about code. I don’t want to stop writing sentences in my own voice. I get a lot of joy from craft. It’s not a universal attitude toward work – from what I can tell, Gen Z is much more anti-work and ready to automate away their jobs – but I’ve always been thankful that programming is a craft that pays a good living wage. I’d be a luthier, photographer, or, who knows, if those jobs were as viable and available. But programming lets you write and think all day. Writing, both code and prose, for me, is both an end product and an end in itself. I don’t want to automate away the things that give me joy.

    – Tom MacWright, The One About AI

    What a great distillation of what makes working on software great! It’s an opportunity to think all day, earning a good wage doing so. Sometimes, to make something of value. Even more rarely, to make something of lasting value. Most of all, to be challenged every day. On the good days, it’s the future we were promised!

    Other days, it’s a bit much. Corporations and all their baggage will get ya down. Deadlines, communication, coordination are how one makes big things, but they have their drawbacks. They (can) drain all the energy and excitement of making something.

    There are jobs that sound exciting from the outside or on paper. Driving race cars and being around motorsport, sounds exciting! But it’s probably a lot of toil, intense competition, and very little invention. Imagineering at Disney is likely immensely rewarding when an idea makes it all the way to the real world or a theme park, every several years. Between those years, it’s likely equal amounts of frustration and the friction of working at a giant company.

    So, for me, building software it is. Even on the days when deadlines and coordination have got me down. Thinking them through to put a bit of the magic of software into the world, it balances out.

    → 1:28 PM, Feb 27
  • Careers are non-linear

    David Hoang, Should managers be technical?:

    Career development looks more like unlocking attributes for a different subclass in a role-playing game, than picking a distinct class that can never change. It’s not a path. It’s a collection of skills and attributes focused on certain outcomes. Applying foundational skills is heavily contingent on your role and responsibility.

    👍🏻 Careers, management or not, aren’t straight lines. The skills you need for your career aren’t a tree with one root. You can skip between various skill trees, if you like! You can go deep, but wide is an option too. The more you know, the more you can delegate!

    You should check out David’s newsletter too.

    A wise person from a Destiny 2 Slack:

    I guess when you’re done with the main quest, you go back and do side quests

    Careers (and lives) are non-linear. Occasionally their trajectories don’t make sense. They may even outright disappoint, in the moment. The silver lining is, they give us unique skills and experience that someone in the world wants if only we can find them. 📈

    → 12:00 PM, Feb 13
  • Squeezing ideas

    Turning a big idea into a more manageable one has second-order consequences:

    Remember, the more complex the issue, the more prone communication is to being lost.

    – Andrew S. Grove, High Output Management

    Communicating complexity is compression. Compressing ideas is loss-y. Can’t get around that. There’s ​no way to convey a complex idea and maintain fidelity​. To work with an idea amongst abstractions is to ​accept that rabbit holes will develop​. And, that sometimes problems will hide in the depths and mazes of those rabbit holes.


    When you compress air, it heats up. The molecules are literally squeezed together, they collide more, and the air gets hotter.

    In combustion engines, compressing air coming into the engine to a higher pressure means you can add more fuel to it and get more power without increasing engine size. But, doing so requires extra machinery, turbochargers or superchargers, and requires an intercooler to cool the air down before it reaches the combustion chamber so it doesn’t explode prematurely. Second-order consequences!

    I haven’t (yet) thought of a snappy analog to compressing ideas — yet. A way to integrate this with a mental model continues to elude me.


    Abstraction, in the every-day software development sense, is compression. All the cautions and mythology programmers tell themselves about abstraction distill down to “compression is great if you can accept the trade-offs”.

    → 2:30 PM, Jan 27
  • Notes on focus and attention

    Focus and attention are inputs to producing excellent things. All the talent in the world won't get me far if I’m not focused or attention isn't working in my favor. Beyond my skills at whatever I’m making (software, teams, products, essays, etc.), I need attention and focus.

    In other words: I want to make what’s important to me: teams, writing, and software. I need focus to decide what to write/build with excellence. I require attention to sustain that focus.


    Henrik Karlsson on multi-armed bandits and focus. First, explore to find what I might want to focus on:

    The trick is to collide your mental model with the outside world as often as possible. This is what exploring does. You think you know the distribution of payoffs of the slot machines, but you try something new. You discover that you were wrong. You update your model.

    This is a life design thing. Get out in reality, seek novelty, try plenty of things, “touch grass” with the world outside my mental model, the more the better. Experience a bunch of things, surround myself with intriguing, intense, or impactful people.

    Surely things could have gone differently for me if I’d done more exploring when I was twenty-something. But, much less of the world was available to me then. More important that I figure out the world needs exploring now and then and that I can explore even with the responsibilities of my forty-something years.

    After the exploration, “exploit” what I’ve found. Choose a few things and go deep on them. Things which resonate with me and make me think “this is a thing that I can do or invest my time and effort in”. I start doing it and that is focus.

    But, really choose those “pillars” of focus. If I pick seven things, I haven’t really chosen. Pick a few of these things, leave several on the cutting floor. Don't construct some wild productivity system where I can spread my energy out over the seven days of the week, over seven areas of alleged focus and get nothing done (except possibly create a wobbly ideology and maybe a video course selling it 🌶️).

    May I recommend the rule of three? It’s great.

    Focus-and-exploit lets the brain work the problem even when offline, away from keyboards and tools. Pro-tip: mundane chores are an excellent tool here. e.g. take a shower, mow the lawn, go for a walk.

    Why would focus compound? Part of it is time. If you care about less, you spend more time doing what you care about most. Also, you are always nonconsciously processing the thing you focus on. So cutting priorities means you work even when it looks like you’re not working. These days, I’ll spend the afternoon playing with the kids, doing the dishes, repairing the houses—being busy in a mind-clearing way. Then, when I sit down to write the next morning, I can type 700 words without thinking. The ideas have been churning in my head, just below the surface of conscious thought, and come fully formed.

    If you're really focused, your brain is always working on those three pillars. It's thinking about whatever it is you're doing, turning over problems, processing that information, compiling it, organizing it while you sleep, and while you do mundane things.


    Austin Kleon suggested a similar approach. When he runs out of writing/creative energy, he cleans his pool. Basically, he takes his thinking mind out of the loop. Lets his physical body do something routine and mundane to invite the creative mind to return. (Sorry, I can’t remember which Austin Kleon thing I saw this as a comment on. 🤦🏻‍♂️)


    If you like this explore and exploit stuff, you’re going to really dig Kent Beck’s ideas about explore, expand, exploit.


    On the other hand, allowing ideas into my sphere of thought from social feeds designed to put me in a bad mood or get me to buy stuff breaks the focus. I need attention.

    Craig Mod, How I Got My Attention Back:

    If I tell people I went offline for a month, it’s like telling them I set up camp on Mars. It hints of apostasy, paganism. Tribes seem to find pleasure in knowing all members suffer equally. But, really, is the situation so dire that we can’t wrangle a little more control? We’ve opted into this baffling baseline of infinite information suck, always-availability. Nobody held a gun to our head. We put our own mouths on the spigot every single day.

    But it’s so delicious. That spigot goo — buoyed by pull-to-refreshes and pings and wily dots. Giving up attention, so seductive.

    I can’t focus if my attention has me thinking of “5 amazing one-takes by Scorsese” or “INSANE Porsche 911 builds”. 🧠🫠 Too much social media feed is an inescapable gravity well of wandering thoughts. Modern, programmed attention makes it difficult to think our thoughts or sustain them.

    However, disconnection is a luxury, and a bit ascetic. The real tactic requires figuring out how to thread the needle, striking a balance between connectedness and Waldenponding.

    So I need guidelines, even when discipline wanes:

    The internet goes off before bed. The internet doesn’t return until after lunch. That’s it. Reasonable rules. I’m too weak to handle the unreasonable.

    What works for me:

    • Remove the glaring offenders in my “attention” life. Mute, unfollow, etc.
    • Set coarse rules that protect my time to focus. e.g., I take the first hour of my day for a writing routine, while my energy is high and the world is mostly asleep instead of eager to distract me.
    • Remove decision-making. I listen to the same album on repeat during my writing session (currently, A Love Supreme). I work through the same five-item to-do list every time to get my energy going.

    Attention and energy are finite. Don’t worry when one or both dwindle. At the end of the day, after numerous meetings, the weekend after a long week. That’s when it’s basically okay to allow a little temptation into your day. Don’t succumb to hustle culture! I encourage you to take a break from crushing it now and then.

    Excellence. This bit started with trying to figure out how focus and attention generate excellent work. In particular, I need more than acumen and experience to make exceptional things, teams, organizations. I need to choose the right thing to focus on. But, tying up excellence with identity can cause misery or generate path dependence. I require honesty with myself when I’m doing great work and when I’m going through the motions to keep the work going. Focus and attention are preconditions for making excellence.

    I Swear, I Really Wanted to Make a 'Rap' Album but This Is Literally the Way the Wind Blew Me This Time – Andre 3000

    It’s all works in progress. Many posts are rough drafts I put out there to keep myself going. I have no idea which ones will stick and which ones will bounce. Plenty of drafts and following the way the wind blows me.


    I know that if I let my attention wander, I will put less out there. Ergo attention. And I know that if I try to make several kinds of things, I will put less out there. Ergo focus.


    Teams and organizations have focus and attention, too. Builders — developers, designers, etc. — focus on their slice of a problem. Teams focus on the problem as a whole. Organizations focus on solving problems that generate an impact on the metrics or goals they’re chasing.

    Priorities are the attention of a team or organization. The negative space in those priorities reflects problems and impacts the group will say “no, thanks” to. That suggests a tidy way to think of personal and group attention; we should say “no, thanks” to attention-sinks which aren’t aligned with our personal goals and priorities. “No, thanks” to algorithmic feeds when our goal is to write, for example.


    (Time to land this thing.)

    Focus is a capacity to get stuff done. To choose a problem and put many hours and days into it. A sense of purpose, if that’s your thing.

    Attention is deciding what the mind is thinking about. Attention can complement focus, or derail it. It’s how minutes turn to hours, in good ways (or bad).

    Shallow focus and attention see us bouncing from one idea to another. Often, without our intention to intervene (i.e., dopamine hits). The good focus and attention turns minutes into hours of engagement and days of interesting work into the weeks and months of a notable career or legacy of work.

    → 8:34 AM, Jan 24
  • Work in progress

    I’ve had this sitting prominently in my Muse workspace for a while. Seems like a good time to deploy it now.

    What if it’s all work in progress? Just sharing/publishing the process as we go along?
    What if it’s all work in progress? Just sharing/publishing the process as we go along?

    Barry Hess, You’re a Blogger, Not an Essayist:

    I’m not going to look down on you for micro-posting on your blog, either. Heck, I might do it myself. I don’t prefer it, though. A blog isn’t Twitter. Just like I don’t think of a blog as something containing 2,000-word, heavily researched posts.

    You don’t have to be an essayist. (Though you can be one if you want!) Don’t let those essayists discourage you from blogging.

    Just write. Just blog.

    Cosign.

    → 7:25 PM, Jan 12
  • Journal for work/life/everything

    Ray Grasso, Long Live the Work Journal:

    Keep a journal for work, champions.

    It’s pretty easy to get started—just create a text file.

    Throw in a new heading each day and write down whatever you did—a single line for each task is usually enough. I put the newer dates at the top so it’s less scrolling to get to the most recent content. Over time you end up with your own little private reverse-chronological blog-in-a-file.

    Each day, dump in commands you’ve run; links to documents you’ve created, reviewed, or read; tasks you want to get done; or goals you want to achieve.

    You’re building a little outboard brain where your work history is just a short grep away.

    Endorsed. Journals are the best PKM impact-to-effort ratio out there. I like DayOne, been using it for more than ten years and thousands of entries. But, anything works! Your notes app, a text file, a document in your preferred word processor. Anything you can search later and access anywhere is good!

    The most important thing is to turn what’s in your head into “words on paper”. That’s when the magic happens!

    → 12:37 PM, Jan 7
  • Notes on strategy and execution

    Will Larson, How to Size and Assess Teams From an Eng Lead at Stripe, Uber and Digg. This pull-quote lead me through some juicy lines of thinking:

    Inflection points are just sustained implementation of a very reasonable thing. Often, the role of the great leader is not to come up with a brilliant strategy, but to convince people to stay the course with a very basic strategy.

    Leaders lead folks in exercising a plan or series of plans (i.e. strategy). Basic strategies are almost certain to outperform complex strategies. Complex strategies tend to leak energy and effort at the seams between the basic/legible parts and all the edge cases and exceptions that generate complexity.

    “Sustained implementation” implies both quality of execution and compounding returns on effort. Sustaining any strategy is more likely to compound effort than frequently changing strategies. But, bear in mind that high probabilities don’t guarantee that an event will happen.

    At the team level, strategy is “why is this project/idea/work important enough to ignore all the other things we could be doing?”. The strategy generates the alignment which makes execution decisions easier. The alignment gives you a principle or goal to return to when things don’t go to plan. The strategy and alignment are guidelines helping teams pull together in the same direction, instead of zeroing out their effort by all pulling in different directions.

    No strategy is worse than no strategy. A lack of strategy is the worst thing, probably worse than having no plan. Any given present/actual strategy is likely to outperform no strategy. So definitely have a strategy, even if it is simple or your first try at having a strategy.

    → 9:57 AM, Dec 6
  • Organize for Discovery

    S-tier programming skill: organize code and behavior such that others can discover and understand it out later without your presence/consultation.

    S-tier writing skill: organize a story or idea within a story such that the reader understands or builds upon it, makes it theirs.

    A-tier relationship skill: organize or set stuff down such that your partner can find it later, without needing to ask you where it is. (Riffing off Merlin Mann here, I think.)

    Ergo: organizing, and empathizing, are skills worth developing.

    It’s a bit of an affordance. Put the idea, code object, etc. where you’d expect to find it or naturally reach for it. Even better, put it where you think someone else would look for it first.

    Tiago Forte, How to Take Smart Notes: 10 Principles to Revolutionize Your Note-Taking and Writing:

    In other words, instead of filing things away according to where they came from, you file them according to where they’re going. This is the essential difference between organizing like a librarian and organizing like a writer.

    All those productivity hacks might pay off, some day!

    → 8:40 AM, Dec 4
  • Sidestep process by sharing tangible progress

    Nat Bennett:

    Cannot overstate the value of regularly delivering working software.

    My single most effective software dev habit is to start with a walking skeleton – a “real” if very stubbed out program that can be deployed on its real infrastructure, receive real calls, visited for real etc. – because of what this does for non-programming stakeholders.

    When they see a real working thing and then they see that thing get meaningful improvements they tend to chill way out and get much easier to work with.

    You can save a week of effort on process with a couple hours of sharing tangible progress.

    Related: you can save a week of planning with a couple hours of programming. You can save a week of programming with a couple hours of planning.

    → 2:55 PM, Dec 2
  • Notes on focus

    I’ve tried a bunch of things, over the years, to find time and discipline to focus on working the tasks and projects that are meaningful to me. Mostly it boils down to actually doing the work and choosing the right kind of work. 🤷🏻‍♂️

    There are two voices

    “Focus on doing the most important thing so that you can get it done. Then, you can do the next most important thing, and so on”, says one.

    “Follow your interests. Turn your energy into some kind of progress. Even if it’s not aligned to the absolute most important thing, all the time”, says the other.

    They’re not-wrong!

    The Important Thing

    If there’s anything more useful than one clear priority, it’s One Important Thing. Maybe they’re two sides of the same coin. Either way, if you know that Thing #1 is more significant than Things #2-10, you have an advantage.

    Priority makes focus. Purpose makes focus. Aligning purpose with priority. That’s a winner.

    The big tent of principles

    That said, it’s possible to pursue smaller things and stay in alignment with priority and purpose. The big-rock/one-important-thing isn’t an identity. They don’t have to represent your life goal. I recommend against trying to stay aligned with a big life goal, lest one miss all the lovely moments and achievements along the way. In other words, stop to say ”well if this isn’t nice, I don’t know what is”.

    The big tent of principles means you can connect the dots from working on something for a short period of time, say a day or month, to what you’re trying to do with the months and years of your life or career.

    Side note: your big principle needs a bit of an open-ended definition. If the principle you’re basing the years of your career is “make a push-button UI that is 5% better”, it’s difficult to fit side-quests into that tent. “Improve the low-hanging fruit in human-computer interface and swing for the fences a few times on drastically improving the state of the art” is a better big tent principle.

    Focus begat finish

    Focus is a means, not an end. The end is finishing. Not almost-done, basically done, or waiting on one little thing before it’s done. Finished means it’s out there, people are reading it or using it or thinking about it or benefitting from it in some way.

    Focus makes the room in your life (and inside your head) to make the thing or polish it or package it or tell the people about it. But focus alone won’t finish it.

    Finishing is dozens of little details that need doing, aren’t doing themselves, and may indeed look dissimilar to monk-like focus. It’s probably an entirely different topic. For the purposes of these notes, remember that it’s easier to finish if you have developed the discipline to focus.

    No

    Saying “no” is the first step. Apps and trinkets and minimalism and meditation are not the key to generating focus.

    To paraphrase Prince: “Nothing Compares 2 No”.

    Saying “no”:

    • Reduces your inbound volume of work
    • Decreases coordination and collaboration multipliers that generate drag
    • Aligns more of the tasks on your list with the thing I said “yes” to

    OTOH, many people feel bad vibes when they hear or say “no”. Say the literal word with care.


    Don’t get so wrapped up in focusing and how other people do it and your ideal schedule and preparing to do the work that you never get around to doing the work.

    → 9:46 AM, Dec 1
  • Zawinski's law, updated

    Every program attempts to expand until it can

    • read email (the original)
    • invite a friend
    • check off tasks in a list
    • record consent to receiving cookies or storing data in the United States (GDPR)
    • store an audit trail (SOC2)
    → 11:32 AM, Nov 25
  • My summer at 100 hertz

    Is there a lost art to writing code without a text editor, or even a (passable) computer? It sounds romantic, I’ve done it before, I tried it again, and…it was not that great. 🤷🏻‍♂️

    0. An archaic summer, even by the standards of the late 1990s

    The summer of 2002 was my last semester interning at Texas Instruments. I was tasked with writing tests verifying the next iteration of the flagship DSP for the company, the ‘C64141. This particular chip did not yet exist; I was doing pre-silicon verification.

    “A baroque painting of a monk programming an old computer surrounded by stacks of paper, broken punch cards, and many discarded cups of coffee” via DALL-E
    “A baroque painting of a monk programming an old computer surrounded by stacks of paper, broken punch cards, and many discarded cups of coffee” via DALL-E

    At the time, that meant I used the compiler toolchain for its ‘C64xx predecessors to build C programs and verify them on a development board (again, with one of the chip’s predecessors) for correctness. Then, I shipped the same compiled code off to a cluster of Sun machines2and ran the program on a gate-level simulation of the new chip based on the hardware definition language (VHDL, I think) of the as-yet physically existent chip3.

    The output of this execution was a rather large output file (hundreds of megabytes, IIRC) that captured the voltage levels through many4 of the wires on the chip5. Armed with digital analyzer software (read: it could show me if a wire were high or low voltage i.e., if its value was 0 or 1 in binary), and someone telling me how to group together the wires that represented the main registers on the chip, I could step through the state of my program by examining the register values one cycle at a time.

    Beyond the toolchain and workflow, which is now considered archaic and generally received by younger colleagues as an “in the snow, uphill, both ways” kind of story, I faced another complication. As you can imagine if you work out what “running a gate-level simulation of a late-90’s era computer chip on late-90’s era Sun computers” implies, from first principles, you’ll realize that at a useful level of fidelity this kind of computation is phenomenally expensive.

    In fact, I had plenty of time to contemplate this and one day in fact did so. Programs that took about a minute to compile, load into a development board, and execute ran over the course of an hour on the simulator. Handily, the simulator output included wall-clock runtime and number of cycles to execute. And so I divided one by the other and came to a rough estimate that the simulator ran programs at less than 100hz; the final silicon’s clock speed was expected to hit 6-700MHz if I recall correctly.

    I was not very productive that summer6! But it does return me to the point of this essay: the time when it was better to think through a program than write it and see what the computer thought of it was not that great.

    1. Coding “offline” sounds romantic, was not that great

    I like to imagine software development in mythological halls like Bell Labs and Xerox PARC worked like this:

    • You wrote memos on a typewriter, scribbled models and data structures in notebooks, or worked out an idea on a chalkboard.
    • Once you worked out that your idea was good, with colleagues over coffee or in your head, you started writing it out in what we’d call, today, a low-level language like C or assembly or gasp machine code.
    • If you go far back enough, you turn a literally handwritten program into a typed-in program on a very low-capacity disk or a stack of punch cards.
    • By means that had disappeared way earlier than I started programming, you convey that disk or stack of cards to an operator, who mediated access to an actual computer and eventually gave you back the results of running your program.

    The further you go back in computing history, the more this is how the ideas must have happened. Even in the boring places and non-hallowed halls.

    I missed the transition point by about a decade,7 as I was starting to write software in the late nineties. Computers were fast enough to edit, compile, and run programs such that you could think about programming nearly interactively. The computational surplus reached the point that you could interact with a REPL, shell, or compiler fast enough to keep context in one’s head without distraction from “compiler’s running, time for coffee”8.

    2a. Snow-cloning the idea to modern times

    In an era of video meetings and team chats and real-time docs, this older way of working sounds somewhat relaxing. 🤷🏻‍♂️ Probably I’m a little romantic about an era I didn’t live through, and it was a bit miserable. Shuffled or damaged punch cards, failed batch jobs, etc.

    I like starting projects away from a computer, in a notebook or whiteboard. Draw all the ideas out, sketch some pseudocode. Expand on ideas, draw connections, scratch things out, make annotations, draw pictures. So much of that is nigh impossible in a text editor. Linear text areas and rectangular canvases, no matter how infinite, don’t allow for it.

    But, there’s something about using only your wits and hands to wrestle with a problem. A different kind of scrutiny you get from writing down a solution, examining it. Scratching a mistake out, scribbling a corner case to the side. Noticing something I’ve glazed over, physically adjusting your body to center it in your field-of-vision, and thinking more deeply about. I end up wondering if I should do more offline coding.

    2b. Ways of programming “offline” that weren’t that great in 2023

    Sketching out programs/diagrams on an iPad was not as good as I’d hoped. Applications that hint at the hardware’s paper- and whiteboard-like promise exist. But it’s still a potential future, not a current reality. The screen is too small, drawing lag exists (in software, at least), and the tactility isn’t quite right.

    Writing out programs, long-hand, on paper or on a tablet is not great. I tried writing out Ruby to a high-level of fidelity9. Despite Ruby’s potential for concision, it was still like drinking a milkshake through a tiny straw. It felt my brain could think faster than I could jot code down and it made me a little dizzy to boot.

    Writing pseudocode was a little more promising. Again, stylus and tablet isn’t the best, but it’s fine in a pinch. By hand on paper/notebooks/index cards is okay if you don’t mind scratching things out and generally making a mess10. Writing out pseudocode in digital notes, e.g. in fenced code blocks within a Markdown document, is an okay to get a short code out and stay in a “thinking” mindset rather than “programming”.

    3. Avoid the computer until it’s time to compute some things

    To an absurd reduction, we use programming to turn billions of arithmetic operations into a semblance of thinking in the form of designs, documents, source files, presentations, diagrams, etc. But, rarely is the computer the best way of arriving at that thinking. More often, it’s better to step away from the computer and scribble or draw or brainstorm.

    (Aside: the pop culture of workspaces and workflows and YouTube personalities and personal knowledge management and “I will turn you into a productivity machine!” courses widely misses on the mark on actually generating good ideas and how poorly it fits into a highly engaged social media post, image, or video.)

    Find a reason to step away from the computer

    Next time you’re getting started on a project, try grabbing a blank whiteboard/stack of index cards/sheet of paper. Write out the problem and start scribbling out ideas, factors to consider, ways you may have solved it before.

    Even better: next time you find yourself stuck, do the same.

    Better still: next time you find a gnarly problem inside a problem you previously thought you were on your way to solving, grab that blank canvas, step away from the computer, and dump your mental state onto it. Then, start investigating how to reduce the gnarly problem to a manageable one.

    1. The TMS320C64x chips were unique in that they resembled a GPU more than a CPU. They had multiple instruction pipelines which the compiler or application developer had to try to get the most out of. It didn’t work out in terms of popularity, but it was great fun to think about. ↩
    2. …in a vaguely-named and ambiguously-located datacenter somewhere. Cloud computing! ↩
    3. Are we having fun yet? In retrospect, yes. ↩
    4. I don’t think it was all of the wires in the chip, as even at the time that would have been hundreds of millions of datapoints per cycle. ↩
    5. Again, simulated and not yet extant 🤯 ↩
    6. Excruciatingly so, by my current standards. ↩
    7. Modulo writing programs to run in gate-level simulations. ↩
    8. At least, for smaller programs in some languages. ↩
    9. i.e. few omitted syntactic idioms ↩
    10. Arguably, the point of working in physical forms is to make a mess, IMO. ↩
    → 8:32 AM, Nov 9
  • Tooling has improved for ambitious software developers

    Tools for working on software in the large1 have improved a lot over since I last considered them ten years ago.

    A sloth cutting an impossible Gordian Knot

    IDEs are better, faster, and have excellent navigation/search features. Full-text search is now somewhat syntax aware and able to index and quickly query large codebases. Tools like Sourcegraph exist on the high end and ripgrep on the low end.

    AI assistants/copilots can wear the hat of “better autocomplete” today and may wear the “help me understand this code” or “help me write a good PR/commit message” hat later. I’m skeptical about the wisdom of handing off the latter to a program, but we’ll see how it goes.

    Applications have made tail -f a better and more legible experience. Somehow, exception trackers and performance monitoring tools don’t seem to have evolved much over the past ten years. This is perhaps a result of market/product consolidation more than an indicator that the category is tapped out.

    It’s hard for me to say how much language is creating leverage for working on software in the large. Ruby and JavaScript were prominent in my daily work ten years ago and are still prominent today. Both have evolved gradual type systems that might make it easier to hold a large program in an individual’s head productively. Both gradual type systems are going through the “trough of disillusionment” phase of the technology hype cycle. I’m cautiously optimistic that some kind of static analysis, whether it’s linters or type checkers, will make writing Ruby and JavaScript less haphazard.

    Notably, deploying software doesn’t seem to have improved much at all for the individual developer. Heroku, in its prime, is still the golden standard. Perversely, Heroku sometimes fails to meet this mark. The options free of lock-in for such a service are limited-to-nascent2.

    In short, tooling has made it easier for fewer people to maintain and enhance larger software. With luck, the options for doing so without paying a monthly tithe to dozens of vendors will improve over the next decade!

    1. We would say “at scale”, now, shamelessly. ↩
    2. Notably, I have not used Kubernetes but the anecdotal data does not lead me to think I’m missing out on much. ↩
    → 12:37 PM, Nov 4
  • Top of Mind No. 6

    I’ve been thinking a lot about setting expectations and goals. I have an idea about setting expectations on how we practice software development in teams and four pillars thereof. They are, broadly: alignment/consensus, accountability/responsibility, transparency/visibility, execution. These seem like four useful touch-points for coaching individuals. More concretely: help teammates drive scope (down, mostly) by setting time expectations and iterating from there.

    The other angle on my mind is using subjective measurements to evaluate changes to human systems. That is, don’t ask a person or team to change how they work and immediately hit a numeric benchmark. Instead, ask them how the change is going and rate it from 1-5, worst to best. If the desired outcome is “know what the team is up to on most days”, ask them to write a status report, but don’t specify a number to hit. Instead, use 1:1s to reflect on how the change is impacting their work, look for advantages or shortcomings to the change in process, and decide how to correct course from there.

    Updates: LLMs are still promising, but not as much for leadership work. Working incrementally, still underrated.

    → 6:50 PM, Oct 26
  • Inside you, there are two or more brains

    David Hoang, Galaxy Brain, Gravity Brain, and Ecosystem Brain:

    The Galaxy Brain thinkers are in 3023 while we're in 2023. They relentlessly pursue the questions, “What if?” Imagination and wonder fuel the possibilities of what the world could be.

    …

    I believe every strong team requires skeptics and realists. Introducing, the Gravity Brain. Don't get it twisted in thinking this is negative—it's a huge positive. If you say "jump," to a Gravity Brain person, they won't say, "how high?" Instead, they say, "Why are we jumping? Have we considered climbing a ladder? Based on the average vertical jump of humans on Earth, this isn't worth our time." Ambition and vision don’t matter if you don’t make progress towards them.

    …

    Ecosystem Brains think a lot of forces of nature and behaviors. They are usually architects and world builders. When they join a new company, they do an archeological dig to understand the history of society, language, and other rituals.

    I’m a natural gravity brain and occasional ecosystem brain. I aspire to galaxy brain, but often get there by of proposing a joke/bad idea to clear my mind and get to the good ideas.

    Which one are you?

    → 7:36 AM, Oct 3
  • I’m not your cool uncle

    I find that playing the “I’m the leader, this is the decision, go forth and do it” card is not fun and almost always wrought with unintended consequences.

    A notable exception is teams that fall back to working in their own specialized lanes1 and throwing things over the wall. Really, the issue is throwing things over the wall, working in your lane isn’t inherently harmful2. Playing the leader card and insisting folks work across specialization in their lane or closely with a teammate whose skills complement their own has fixed more things than it complicated. More specifically, the complications were the kind of difficulties a high-functioning team would face anyway, i.e., “high-quality problems”.

    Now I wonder what other scenarios justify playing the power dynamic or “I’m not your cool uncle” card to escape an unproductive local maximum.

    1. e.g. back-end, front-end, mobile, etc. ↩
    2. Assuming you’re adept at communicating progress and avoiding rabbit holes ↩
    → 10:00 AM, Sep 29
  • I got better at estimating projects with intentional practice

    I like the idea of practicing1, in the musical or athletic sense, at professional skills to rapidly improve my performance and reduce my error rate. When I was a music major2, I spent hours practicing ahead of rehearsals, lessons, and performance. Until recently, I was unable to conceive of how I might do the same for leadership.

    Estimating the time and effort of a software project is error-prone, even when one considers how error-prone the activity is3. Reasoning about a clearly defined functional scope is a classic "unreasonably difficult even when accounting for how difficult it is" problem. Everyone wants to know how many days a project will take, but few try to understand the myriad, interconnected ways the number of days can grow surprisingly large. (More on that later.)

    What I figured out was, practicing at estimates is as “repeatable and atomic” (see below) as scales are for music. The material one needs as input to practice at estimating is available on the marketing websites of the numerous startups, technology, and software product companies out in the world. Any number of feature or pricing pages are sufficiently interesting to ask myself, "how would I start building the functionality or feature advertised here?” Then, do a 15-60 minute exercise of breaking it down, thinking about scenarios, discovering risks and dependencies, laying out a plan, and even thinking out the high-level technical design.

    This is even easier if I start from products I already know well from daily use. Most developers know GitHub's features pretty well. Starting from their Pull Requests marketing page is a familiar starting point. This lets one work on the mechanics of thinking holistically about the functional scope. Then, I can get down to details about how to build a (hypothetical) wholly new capability or feature into a (hypothetical) product.

    This insight allowed me to move past a "I guess estimating is a struggle bus that could limit my growth" mindset. Now I feel like "I can get as good as I want at this by doing the reps", much like practicing at music or free throws4.

    The recipe for practicing at estimating

    1. Think up some kind of project I might do in the future or
    2. Find a software product page on the web and use that as an imaginary requirements document5
    3. Spend 20 minutes going through the motions of how I like to estimate projects (break down scopes, think through happy/edge cases)
    4. Spend 10 minutes breaking down the work, identifying the risks, etc. – use an outline, sticky notes, a whiteboard, whatever works
    5. Reflect on what I came up with, how I’d tackle it differently next time
    6. Rinse and repeat. Take a different approach to the same project. Estimate a different project. Try the exercise with a few of my favorite colleagues/collaborators and see how it comes out differently.

    The most important thing to keep in mind: formality is not required when practicing. It’s about low-stakes and fast iteration.

    Practice makes estimating less imperfect

    Practice can make software estimates more useful. Not more prescient, necessarily. But definitely, I can produce better outcomes by practicing around the process of planning and estimating software.

    Practice works because it is atomic and repeatable. I’m using database terminology a little oddly here.

    Atomic, in the sense of database transactions, means I can "return to square one" at my discretion without imposing on anyone else. To carry the metaphor, practice sessions are more atomic than rehearsals or performances. I can throw away the results of my estimation practice session without ruining anyone’s project/roadmap/schedule.

    Repeatable means I can estimate similar projects over and over again until I’m satisfied I’ve reached the level of skill mastery necessary. To carry the metaphor, I practice a passage or shoot free throws until I’m confident I can perform it correctly the vast majority of the time.

    The great thing about practicing at estimating fake projects is it will make me better at estimating real projects. Like they say: practice makes perfect.6

    Equally great, I’m not accountable for fake projects. I don’t have to worry about breaking things down incoherently or overlooking a key bit of functionality. Hopefully, I find it upon review and reach a state of coherent, complete estimates. But the risk of one individual practice estimate ruining someone’s working week is non-existent.

    The web is rife with practice material. Grab a short product description, pitch, etc. Marketing and feature pages on a favorite app’s website work great. Previous projects or imagined software work too. Maybe jot down prior assumptions, e.g., I’ve already built authentication or a mobile app or payments.

    With a “practice” functional scope and some constraints in mind, it’s time to start practicing. Ask where the seams are, how to split things up, what are the risks, could this part be omitted, do we have prior art for this, etc. Make a list or board or mind-map or whatever. Organize it by concept or how I would tackle the project. Look for gaps in how I would explain the plan or pitch it to my team. These all work well for me, but you may estimate differently. That’s fine, and the point! Try different approaches and see what is effective, efficient, and generative.

    I can practice at taking the idea for a software project, feature, enhancement, etc. and turning it into a plan for how to build it. When I practice at this, I improve at finding risks, breaking down problems, writing down ideas, coming up with novel approaches, considering how to apply technology to solve problems, deciding which parts of the problem to focus on, etc. All of this yields better plans for building the project, which leads to better execution. Somewhere in the middle of those plans come estimation, which I’m getting more reps at, so hopefully I’m getting better at it.

    Planning and estimating software forces me to turn over stones I may otherwise overlook. It gives me an opportunity to tackle kinds of software I may not otherwise build, or even learn how to build software I may not otherwise build at a high level. For example, I have no idea how to build a game, but practicing estimating a game project sends me down a discovery process that will certainly teach me something7.

    Rinse and repeat. Do this over and over until you are as good as you want to be at estimating software. Maybe do this with your team. It’s a little harder, but teaching everyone to do it will raise all ships.

    A crucial element of practice is immediate feedback; “how’d I do?”. Practicing at estimation gives me one kind of immediate feedback in the form of revealing more of the puzzle as I go. On the other hand, I (still) don’t get the crucial feedback that makes software estimation so difficult in the first place — measurement of accuracy and precision. Software estimation is hard because a lot of the factors that go into how long building software takes are invisible and unpredictable.

    Reflections on practicing at estimating software projects

    So, I found it possible to quickly gain experience at the “guessing at numbers” part of estimation. This bit is amenable to iteration – I can work through a stack of software project ideas, call upon my experience, and guess at what the tasks are and how long they might take. I did several of these over the course of a couple of weeks. I found it effective enough, I no longer felt like I was “working from behind” when called upon to estimate how the effort and time for a project at work.

    Lately, I’m using Jacob Kaplan-Moss’ approach to estimation. List out the tasks, score them by effort and risk/variance. Add up the numbers and get a sum. Decide that number is fine, or investigate the critical tasks (large effort or high variance) to get a better idea how to break them into less risky tasks.

    Practice makes challenging activities something you can rinse and repeat.

    Key caution: this kind of iterative improvement is not the same kind of activity as Platonic practice activities like shooting free throws or methodically learning a piece of music. To use a coarse analogy, practicing at estimating software is like practicing free throws, but I can’t see or hear the ball after I release it. There’s no feedback loop, I can’t know if the shot went in, bounced off the backboard, or missed entirely8. In other words, everything that happens after the initial estimate is the wicked problem that defies both practice and systemic, industry-wide improvement.

    On the other hand, this form of the activity does look like basketball or musical practice because it’s in a safe bubble. My practice at estimating doesn’t put real projects with real people working them at risk. If I try something unusual, no one has to put up with it later. This affords trying multiple approaches to the same problem and experimentation. I find this is the key insight – for some non-coding leadership/management activities, it’s possible to practice at some part of the activity and gain confidence in running that part. Possibly, not the whole thing, but at least a slice of the process is improvable without relying on live people and live work for non-methodical iteration and experimentation.

    In short…

    Estimating software projects is a relatively easy, learnable planning/brainstorming creative task coupled with wicked expectations of the ability to predict the future in terms of outcomes, unknowns, risks, and things that just don’t go my way. I can practice at the first part.

    No software estimate is perfect. The world is full of surprises9. Focus on the easy part, decomposition and discovery. Tackle all the execution stuff downstream separately.

    1. This thinking was inspired by an Andy Matuschak Patreon post on practicing at sight reading on piano ↩
    2. Double bass performance, orchestral, first year. I switched because it was far easier for me to spend six hours in front of a computer than in a practice room. Caveat raptor. ↩
    3. Even multiplying estimates by two is considered a pretty-okay practice, but is often insufficient for a good, let alone reasonable, answer. ↩
    4. Which I have done very little practice at and, accordingly, am not very good at. ↩
    5. Whether a marketing page is a better product spec than what you receive for normal projects in your org is a matter of variance. ↩
    6. Caveat: this isn’t intense concert pianist/pro athlete level practice. If you do end up producing >99% perfect estimates, please all of us know your secret! ↩
    7. It may prove that what I learn is how little I know about actually building game software! ↩
    8. It’s perhaps not that bad. Perhaps it’s more like the difference between shooting free throws and scoring field goals in a basketball game. I have no hope at the latter if I can’t perform the former at a high level. ↩
    9. Sorry ‘bout that! ↩
    → 10:19 AM, Aug 23
  • When finished isn’t done

    The work is done, the post is published, the code has shipped, the boxes are all checked.

    And yet, it remains in my head. The bit of code I’d like to revisit, an edge I couldn’t round off, a paragraph that doesn’t fit like I want it to, a workflow we didn’t improve upon, a conversation about trade-offs that went sideways…

    The work is more than the work, more than an end. It’s emotions and memories. A new way of thinking, experience and wisdom newly integrated with what I’ve done before. The start of something new, with this finished work as the prologue that sets the stage for the next story.


    Previous tasks continue to consume attention even after switching. This is especially true for anything that causes strong emotions. I find it hard to concentrate if I’m opening (Slack) every 15 minutes and every time seeing that thread where someone is arguing with me and they’re totally wrong and how can they even believe what they’re saying and what was I doing again? — Jamie Brandon, Moving Faster
    1. Acknowledging and managing emotions is a productivity/go-fast hack
    2. Really, don’t dwell on people being wrong. You can’t control it. Just keep going.
    3. Absent people and emotions, completing a task doesn’t mean it’s out of our heads. Account for that in planning the day or projects.

    Often, things are only getting started when I check that box.

    We call it perfectionism when we hold the work back to make one last tweak, another small improvement. Perfectionism is pouring myself into one checkbox for weeks or months at the expense of all the other things I want to do. It’s not so much seeking perfect, but an inability to let go and get started in earnest.

    To the contrary, every day I’m more convinced that perfect emerges from checking that first box. Putting the work out there, starting the next checkbox (of several dozen), accumulating and shaping something more perfect.


    Everything finished is the start of something else.

    → 2:01 PM, Jul 8
  • Notes on narrative for engineering leaders

    Alex Reeve, 22 Principles for Great Product Managers:

    You have to own the narrative. When there’s a narrative vacuum, people will “creatively” fill in the blanks themselves—and you might not like it. Losing control of the narrative can be incredibly disruptive to your team’s ability to deliver.

    – (Alex Reeve, 22 Principles for Great Product Managers)

    Same goes for plans & projects. If you don’t have a plan, someone else will. You may not like their plan.

    Telling the story of a goal/project/initiative isn’t manipulation1, it’s setting the vision.

    All narratives compress out important details and trade-offs as an expense of clarity and noteworthiness (i.e. an un-memorable narrative is not a particularly good narrative).

    Narrative is is a fantastic skill to have as an engineering leader. The more you can convey your ideas, goals, projects, and initiatives as a narrative, the more you can get people on the same page. It’s also a fun skill to acquire. It’s all around us in culture. It’s one of the few things where you can improve in your profession by paying attention to how movies, television, or fiction are structured. (Highly recommended: Every Frame a Painting)

    1. Bad-faith narrative construction exists, please don’t act in bad faith. ↩
    → 9:34 AM, Jun 9
  • Three meditations on wins

    Leaders (and managers) are successful to the extent that their teams and peers notch wins. Former Intel CEO Andy Grove calls this the “output” of a manager, and wrote the book on it1.

    Easier said than done! What is it for a lead to create wins (aka output)?

    1. Choose games that are winnable

    Only play games you can win.

    • Warren Buffett or the Beastie Boys (probably)

    Our time is highly constrained. Saying “no” is an underrated and under-discussed leadership skill. Saying no on behalf of my team, peers, or organization, I’ve created focus on a (potentially) winning effort.

    Some great reasons not to play a game2:

    • The opportunity, as presented, is not yet small enough in scope to notch a win in the time available to work the opportunity. Find a smaller win in the presented opportunity that will give you a hint as to the real potential of the bigger project.
    • The calendar time necessary to run the project or ongoing effort to completion (notch the win) is dominated by process, coordination, and bureaucracy. That is, try again when there is a way to realize the impact with less overhead/organizational drag.
    • There’s a gap between the desired/supposed outcome and the project(s) that could realize that outcome. The immediate win is to research/brainstorm/write your way to connecting outcome with action(s).

    Pro-tip: provide feedback on not-yet-winnable games in the form of “I don’t yet know how to win that game, let’s start by fixing that”. No one likes pessimism, cynicism, or shutting down all the project ideas. That said, it’s fair to provide constructive feedback that will improve the idea or bring it closer to action/win-ability.

    2. What counts as a win?

    Once something is out in the world, it’s a win. Publishing an article, releasing a feature to your customers – those are definitely wins.

    Getting something out of your team or head, that’s a sort of win. Rolling out a new process or tool is some kind of win. Worth sharing! But it doesn’t directly improve what customers are paying for, so focusing entirely on this kind of win doesn’t count.

    Wins have to change your company’s world in some tangible way. The change need not be objective or quantitative; a subjective/qualitative survey is enough!

    If what you’re recognizing as little wins doesn’t yield bigger wins, then it’s time to reflect on what you’re encouraging.

    3. Avoid short-term thinking, build momentum with little wins, build big wins

    A culture of thoughtfulness about outcomes, potential, impact, and trade-offs makes 1 and 2 happen.

    Loud voices may try to convince you that un-winnable games have lots of promise. Urgent voices might tell you counting something as a win and moving on is the right move.

    Moving the goal-line closer, so you can recognize a win, is expedient and productive, occasionally. Other times, moving the goal-line is self-defeating.

    It is often difficult to stick with long-term projects. There is so much other stuff to work on, all of it intriguing. Other folks in the organization will want to know how much of “all of it” we could produce in the current and next quarters.

    The challenge is to stay the course, believe in the purpose, and stack all those little wins, every week, until the big win takes shape. Tell your colleagues about the big win’s emergence…

    In short

    1. Choosing what to work on (or not) is of crucial importance.
    2. Recognizing the right kinds of progress makes it easier to stack little wins on the way to big wins.
    3. Exercising the discipline to stack meaningful progress (wins) is the engine for generating big outcomes.
    1. High Output Management. See also, GitLab’s notes on the same. ↩
    2. Would a whole post on indicators of losing/un-winnable games come off as too cynical? ↩
    → 8:18 AM, May 10
  • Improving when you can’t rinse and repeat

    You can’t practice at some things. Putting the cat back in the bag or the toothpaste back in the tube. The undoable, the things that you can’t unsay. The measure twice cut once stuff.

    In those cases, a little preparation and reflection go a long way. I think about what's important to say or verify before I say/do the undoable. Afterward, I reflect on how things went, if I learned anything surprising, and how I can improve the process next time. Ideally, I write all this down, so I don't lose any wisdom for the next time I'm faced with a similar challenge.

    I'd normally say rinse and repeat here. But the point here is there is no rinse! There is only setting myself up for success when I find myself facing a one-way door.

    → 1:38 PM, May 7
  • Top of Mind No. 5

    Like everyone (it seems), I’m exploring how large language model copilots/assistants might change how I work. A few of the things that have stuck with me:

    • Use LLMs to reduce the cost of doing things, there by increasing ambition. That is, reducing cost increases demand.
    • Using LLM prompting to think through/design a new bit of program functionality. If one can manage to write a generic prompt, without proprietary information, you have given many programmers a much wiser pair than they might normally have.
    • Use LLM flexible tool for thinking through problems or solving them outright. GPT4 is like rolling a REPL, a junior developer, and a conversational partner into one very flexible toolkit.

    My take right now: GitHub Copilot is the real deal and helpful, today. On the low-end, it’s the most useful autocomplete I’ve used. On the high-end, it’s like having a pair who has memorized countless APIs (with a somewhat fallible memory) but can also type in boilerplate bits of code quickly, so I can edit, verify, and correct them.

    I don’t expect the next few products I try to hit that mark. But, I suspect I will have a few LLM-based tools in my weekly rotation by the end of the year.

    → 8:32 AM, Apr 26
  • Err the Blog, revisited

    Before there was GitHub, there was Err the Blog. Chris Wanstrath and PJ Hyett wrote one of the essential Rails blogs of early Rails era. Therein, many of the idioms and ideas we use to build Rails apps today were documented or born.

    I’d figured this site was offline, as are most things from the mid-2000s. ‘Lo and behold, it’s still online in its pink-and-black glory. Lots of nostalgia on my part here.

    There was a Big Moment here, in my career and Ruby/Rails, where an abnormal density of smart people were together in a moment (if not a community) and the basis of my career took shape. It was good times, even if we didn’t yet have smartphones or doom-scrolling.

    Allow me to reflect on what I found as I went through the archives.

    How we built things back then

    Rails circa 2.x was a quite unfamiliar game to the modern developer. REST conventions for CRUD controllers had just taken hold, and were not yet the canonical way to structure Rails code. There was a lot of experimentation and many of the solutions we take for granted today (namely, dependencies) were extremely unsolved back then.

    DRY Your Controllers — err.the_blog – ideas about CRUD controllers before CRUD controllers were the thing in Rails (2.0 I think?). That said, if you were to write this now… I'd have issues with that. 😆

    My Rails Toolbox — err.the_blog – this probably represented the state of the art for building Rails in its time… 17 years ago. 👴

    Vendor Everything — err.the_blog – I followed this approach on my first Rails app. It was a pretty good way to keep things going for one, enthusiastic developer at the time. But RubyGems, Bundler, etc. are far better than vendor’ing these days. And, one of the crucial leverage points for working in the Rails space.

    How we built things back now

    Some things stay the same. For example, the need to fill in the gaps between Rails’ conventions for organizing your app, enhancing Ruby via ActiveSupport, and the lack of a suitable approach to view templates that satisfies writing code, testing code, and building front-ends.

    Organize Your Models — err.the_blog – early memories of attempting to organize files in a Rails 1.2 app despite numerous headwinds presented by Rails itself. (IMO, organizing a Rails app by folder+namespace has really only started to work after Rails 6.0).

    Rails Rubyisms Advent — err.the_blog – a love letter to ActiveSupport's extensions to the Ruby language. Many of these are in the Ruby language now, thankfully! ActiveSupport (still) rubs some folks the wrong way, but it remains one of my favorite things about Rails.

    View Testing 2.0 — err.the_blog – amazingly, there's still no good story here. It's all shell games; write e2e tests instead of unit tests, use object-like intermediaries instead of ERB templates, etc.

    How we stopped building things that way

    Rails has always had flawed ideas that need re-shaping or removing over time. Mostly in making ActiveRecord as good of an ecosystem participant as it is a query-generation API.

    with_scope with scope — err.the_blog – ActiveRecord scopes are way better now! I think with_scope remains, at least in spirit, in the Rails router API.

    ActiveRecord Variance — err.the_blog – wherein our heroes discover inconsistencies in AR's find* APIs and patch their way to more predictable operation thereof.

    How I was even more excited about Ruby

    Err the Blog was not first on the Rails hype wave of the mid-2000’s. But, it was consistently one of the best. Every time a new post was published, I knew it was worthwhile to make time to read the latest post. I learned a lot about my favorite things about Ruby from Err: writing little languages and Enumerable.

    Pennin' a DSL — err.the_blog – I could not read enough posts on building DSLs in my early Ruby days. It was the feature I was excited about in Ruby. Thankfully, it's a lot easier to do 'macro magic' in Ruby these days. And, hooking into the idiomatic ways to write Rails-style declarative bits is much better now.

    Select a Reject — err.the_blog, Allow Me to Inject — err.the_blog – love letters to Enumerable, my favorite thing about Ruby. And Full of Ambition — err.the_blog – fan fiction about Enumerable and ActiveRecord finally uniting in a loving relationship.

    We have to go back

    If you liked this, you may also enjoy revisiting:

    • has_many :through – Josh Susser’s blog was one of the first to explain how Rails works and how to leverage it
    • Red Handed – _why the lucky stiff’s blog
    • Envy Labs – a Rails blog from the Rails Envy folks, Gregg Pollack and Jason Seifer
    • Caboose – part community, part collective, an early nexus of Rails talent

    And so, I come to the end of my nostalgia. Now, I must go forward.

    → 7:45 AM, Apr 14
Recommendations

Personal websites are rad

  • Austin Kleon: austinkleon.com
  • Escaping Flatland: www.henrikkarlsson.xyz
  • Craig Mod: craigmod.com
  • Rands in Repose: randsinrepose.com
  • Ribbonfarm: www.ribbonfarm.com
  • Manuel Moreale: manuelmoreale.com
  • Kent Beck: tidyfirst.substack.com
  • Rasmus Andersson: rsms.me

Blogroll as: OPML | JSON

  • RSS
  • JSON Feed