A couple of weeks ago, I talked about r/K-selection and mentioned two kinds of ideas: the mutate-through-replication dandelions and capacity-preserving elephants.
I remain curious about the conditions in which dandelions thrive. Here are some initial thoughts on the subject. To narrow the broad designation of “ideas” a bit, I am going to focus on a special case: innovation on top of APIs. That is, new ideas that emerge while writing code that consumes some set of APIs.
Let’s suppose we’re just starting down the process of designing a new API. Very early, we decided that we want this API to spur dandelions. We did a lot of thinking and realized that our fledgling enterprise will benefit greatly from employing the r-selected strategy.
Why would we want to do that? Primarily, the r-selected strategy works best in environments that aren’t (yet) predictable or stable, where the rate of change is high. For example, we might be entering some new problem space and we want to lean onto the “wisdom of the crowd” to explore it. Or perhaps we’re a newcomer and we would like to convert the budding enthusiasm in the problem space into as many dependencies on our services as possible (if you’re looking for a case study on both, check out Stable Diffusion playbook).
What are the conditions that we need to grow dandelions? How might we design APIs that encourage dandelion-like innovation?
Using the r/K-selection in biology as our guide, we see four key conditions: high reproduction rate, small size, short generation time, and wide dispersion radius. Yes, just like dandelions.
Translating these conditions from plants to ideas, I came up with: interest, legibility, velocity, and access. Let’s go through them one by one. You know me. I love my “let’s go through them one by one” bit.
First, this API actually needs to promise to unlock exciting new opportunities. This leads me to the first condition: interest, which roughly matches the “high reproduction rate” in biology. Exciting ideas are contagious. They spur lots of new ideas, churning them out at a high rate. They don’t even have to have concrete value behind them – just a promise of something big and potentially groundbreaking. This sometimes leads to formation of a bubble of hype around them, like with Web3 and the NFTs. Such bubbles, while not healthy in the long term, are a strong sign of the interest condition being met.
Interest is not an intrinsic property of the API design, but rather the property of the technology behind it. Researchers teased the developer community with the tantalizing potential of AI-generated media for years now, building up the interest in the underlying technology. It was OpenAI and then Stable Diffusion who capitalized on this interest and shipped first publicly-accessible APIs that enabled developers to actually play with technology. The resulting wave of innovation was nothing short of astounding – and it keeps going. There ought to be a clock of “days since Stable Diffusion was released” somewhere, because the quantity of interesting new ideas born out of that event feels unbelievable when put in the context of the little time that had passed. Again, a great example of the interest condition being met.
To give you a counter-example, consider OpenSocial, a cool idea from way back in 2007 that started with much fanfare at Google and ended up dying quietly in the W3C effort graveyard. Even though yours truly did end up playing with it, very few others did. Was it ahead of its time? Was it too obtuse? Was it the XML thing? We will never know. But if your API adoption patterns are looking like those of OpenSocial, check the pulse of the community interest.
Another significant condition is legibility. To allow an idea to spark imagination and produce new ideas, it must be easily understood – even if partially. I correlated this one with the biological counterpart of “small size”. Metaphorically, think of it this way: an idea that is light and small like a dandelion is much easier to grasp than the weighty idea-elephant. A litmus test: can a useful program built with our API fit into a tweet? The deca-LOC framing is useful here, though it’s not just the number of lines of code.
One of the key tenets of the WebKit open source project at one time was the idea of self-explanatory code: is your change making the code more or less easy to read? There were some who even suggested that adding comments is somewhat of a code smell: if you have to explain what it does, then perhaps maybe you could write it more eloquently instead?
While I don’t take this extreme point of view, I appreciate the sentiment. Choosing the idioms and concepts that make the code concise while capturing the key thrust of the idea behind the API is difficult work and is full of difficult trade-offs. Sometimes it takes several iterations to arrive at a mental model of the API that clicks with most people. When designing for dandelions, opinion is front and center, and the easiest-to-grasp concepts win over the more obtuse ones – even if the latter are more powerful and flexible.
Speaking of WebKit, and similar large codebases. A key ingredient of legibility is the ease with which an idea can be separated from other ideas. How discrete is it? How easy is it to spot this idea and lift it out? WebKit has a ton of great ideas in its code. I know, I lived in that repository a few years back, and I bet there are even more flashes of brilliance now. However, to spot them as separate ideas, we have to spend a bunch of time understanding how all the surrounding neighboring ideas fit.
This is one of the challenges of implementing r-selected strategies in large code repositories. Now matter how we try, our dandelions end up being somewhat elephant-like.
The third condition has to do with how quickly the ideas borne out of interacting with our APIs can turn into other, new ideas. This is not necessarily a property of the API itself, but rather a setting into which it is born. Loosely, it corresponds to “short generation time” in biology. Velocity is commonly called “tight developer feedback loop” in developer experience jargon, and yes, it’s that, and a bit more. I see it as somewhat two-fold: time to result and effort to copy.
Time to result is the time it takes between making a change to the code and seeing the results of the change. Back when I first started using computers, I remember working with a particularly old piece of equipment that provided the output of my program only as a paper printout – and the printer was across the hall from the monitor and keyboard. Time to result included jogging out of the lab and into the computer room, where massive printers hammered out loudly our many failures and rare successes. Paper jam? Well, you might have to run that job again. Even just capturing the simplest idea into working code was a multi-hour (and sometimes, multi-day) process. That mini-computer was from the pre-dandelion era. The shorter the time to result, the better velocity of an idea.
Effort to copy is an adjacent concept. How much effort does it take to copy an idea? Is it a complicated process? Or is it just one click? A somewhat unexpected, yet obvious-upon-inspection factor here is organizational boundaries.
Back when I worked on Google Gears as an external-to-Google contributor, I was puzzled at the weird phenomenon: to land, my patches would need to be sent over email as diff files. The open-source directory did not contain any commits from individuals: instead, every commit was made by a bot. After a couple of days of submitting the patch, the bot would dutifully add my commit to the repository. What the heck was happening?! As one of the engineers explained, the actual source of truth was on the other side of the wall that separated the inside of Google from the outside. To land the code, a Google engineer had to patch it in, have it reviewed, and then let the bot take it outside. What I was working with was a mirror, not a real thing. Sure, the automated bot made things easier. But across the wall like this, the effort to copy is still high – and not just for the code going out. If there is some really cool new innovation on the outside of the wall, an organization has little choice but to rebuild it – often from scratch – on the inside.
On the other side of the spectrum, Github’s “fork” button is a great example of intentionally lowering effort to copy. Want to play with an idea? Click and start making it yours. As another illustration, both effort to copy and time to result are combined delightfully into various read-eval-print loop (REPL) tools that sprouted all over the place in the past decade. Though my first love was JS Bin (hi Remy!), one of my favorite ones today is Replit, which seems to be designed by someone who deeply understands the concept of dandelion gardening.
The final condition is access. It seems that, to stimulate r-selection, we need a large pool of minds that our APIs can come in contact with. To generate many ideas, we need many minds – or to have a “high dispersion radius”, speaking biologically.
What does it take to start using our API? What are the barriers that the person must overcome? For example, if we decide to provide our API in some programming language that nobody ever heard of, we are increasing the barrier. To access our APIs, people first have to learn this language.
Dandelion-growing needs space. If we’re planning a small group within our organization as the potential users of the API, we are unlikely to get any benefits of the r-selected strategy. This is often counterintuitive in organizations that pride themselves on engineering excellence. It feels like we should be able to just get a couple of really smart folks to play with the API, and they will figure out some interesting possibilities… right? Well, maybe.
But if we are aiming to harness the r-selected strategy, we need to stop looking for experts who might give us great insights. Instead, we need to open the API up as broadly as possible and let the wave of hobbyists and enthusiasts wash over it. When growing dandelions, think quantity over quality. Skill and expertise are a barrier.
Additionally, to maximize the number of ideas connecting with each other, I need to make them easy to find and browse. Can a seed of an idea be easily discovered? Can I trace its heritage and find earlier seeds on which the idea was based? Can I see who else is playing with it currently? And no less importantly, who can find my idea?
A gardener’s guide
Putting these all together, we can build a simple compass. The four conditions form an arrow that points us toward dandelion-like growth:
- Is the underlying technology that the API exposes interesting? Do we anticipate developer buzz around it?
- Is the API mental model easy to grasp? Can developers’ ideas be expressed in simple, elegant code? Is it free of dependencies that developers might be unfamiliar with?
- Is the setting into which we release the API offer REPL-like iteration speed and one-click copying of ideas?
- How large is the pool of people who could conceivably use the API? Is the cost to entry minimal? Is the list of prerequisite learnings short? Is it easy to find similar or different ideas and understand how they came together?
There are a handful of folks that I know who seem to intuitively understand these conditions, and their approaches to API development reflects that. For the rest of us – myself included – here’s hoping that this compass will serve us well in our dandelion-growing pursuits.