It has been said that a novel user interface idea is not a durable differentiator for a product. The cycle is like this. An idea is conceived and integrated into a product. It provides value to the users of the product, and, initially, brings market differentiation and success to the product. But then it’s copied into other products and the market differentiation is lost.
However, an innovation is not universally adaptable. For example, the New York Times could not integrate pull to refresh into the traditional layout of their front page.
Pull to refresh is a set of interlocking interfaces -
- A single column
- …on a touch screen
- …of pieces of content
- …with the same structure
- …arranged in chronological order
- …that can be scrolled vertically
The front page is extremely well suited to these sub-interfaces. Its interface can integrate with four of the six pull to refresh sub-interfaces - 2, 3, 4 and 6. But it’s not structured as a single column (1) and it’s not arranged in order of newness (5). These mismatches are enough to make it difficult to integrate pull to refresh.
But not impossible. Thinking of the traditional New York Times front page as a single interface isn’t quite right. Just like pull to refresh, it’s really a set of interlocking interfaces -
- Pieces of content that are headlines and blurbs.
- Lists of pieces of content
The most important interface, the headline and blurb, is compatible with pull to refresh. Take a bunch of them, put them in scrollable column, and, boom, they’re ready to integrate with pull to refresh.
So an old interface can be reconfigured to integrate with a new interface. A few observations.
First, integrating interfaces can be more or less harmonious.
In the case of pull to refresh and the New York Times front page, the integration was reasonably harmonious. A grid-like front page became a list. The pull-to-refresh spinner lives at the top. The fact that the list of content items that gets refreshed is separated from the spinner by the unrelated masthead, date and ticker only brings a small amount of discordance.
The integration of disappearing photos into Instagram was less harmonious. Stories live in a separate part of the product to the old posts interface and bring a new set of interface conventions for interacting with them. The differences between the post interface and stories interface were so great that they had to be made separate.
Second, in integrating a new interface, some of the advantages of the old interface are lost. The grid-like front page of the New York Times made important things prominent whilst still showing less important things. The pull-to-refresh version is able to show one most important thing. But the hierarchy of importance has been lost.
Third, in integrating a new interface, some of the advantages of the new interface are also lost. In the pull-to-refresh version of the New York Times, unless the newest piece of content is also the new top headline, the newest content is hidden below the top headline.
Fourth, every product is trapped in the past. Each part of a product’s interface was designed for the world of that moment. But the world changes. So the product is designed for a world that, to some extent, no longer exists. The product can be changed to meet the conditions of the new world, but this is a painful process.
Further, it’s even difficult to stay up to date by copying innovations. Those innovations are adapted for conditions that the product is not adapted for. Pull to refresh is adapted to a world of large volumes of regularly updated content. That’s not the world of the New York Times.
So, seeing an interface as a set of sub-interfaces, each of which needs to integrate with other interfaces, has helped me understand why it’s not easy to successfully copy a UI innovation. And why products get stuck in the world in which they were born.
I used to believe that every book has an objective value. And I used to believe that this value is fixed and universal.
Now, I believe it’s much more useful to say something in this form: this book has this value to this person in this context.
For example, Mindset by Carol Dweck was life changing to me when I read it in 2016.
The “me” part is important because I grew up thinking that intelligence is fixed and my skill in each activity I tried was based on talent and was fixed. So I thought I should to do the things I had a knack for, and I thought that the things I found difficult would stay difficult. Learning about a growth mindset was extremely valuable to me.
The 2016 part - the context - was also important. I’d just spent the last three years working at the Recurse Center, a place and community suffused with the idea that people can grow. I was primed for these ideas.
A second example. Around ten years ago I read You and your research by Richard Hamming. This is an essay by a mathematician who did ground-breaking research into telecommunications. He relates this anecdote:
I had been eating for some years with the Physics table at the Bell Telephone Laboratories restaurant…Fame, promotion and hiring by other companies ruined the average quality of the people so I shifted to the Chemistry table in another corner of the restaurant. I began by asking what the important problems were in chemistry, then later what important problems they were working on, and finally one day said, “If what you are working on is not important and not likely to lead to important things, then why are you working on it?” After that, I was not welcome and had to shift to eating with the Engineers.
I read that ten years ago without effect. I read it again a couple of years ago and it led me to the work I’ve been doing for the last three years. The same text and the same reader. A completely different outcome.
I think what changed is my context. Ten years ago, if I’d even tried to work on foundational problems in my field - programming - I’d just have kind of paddled around and had no idea how to make progress. I didn’t have the knowledge of the history of computing or programming to be able to make any kind of headway. In 2021, I did, because I’d accrued it.
The idea that a book’s value is best judged alongside the notional reader and their current context has some corollaries:
First, reading the books that your heroes cite as important will not necessarily be rewarding. If you admire Bret Victor for his work on computing interfaces, only some of his library will be high value to you because his library also includes lots of books that have nothing to do with UI.
Second, yes, it’s likely that “great books” may be high value in some more universal sense that is independent of reader and context. And, yes, this high value may come from something inherent in the quality of the books, rather than from the fact that they are about themes that are more relevant to more people. Yes, I probably wouldn’t dispute this. But I suspect that relevance to person and context is a better guide to what to read.
Third, book recommendation systems based on your reading history can be helpful, but only so much. You, now, are not represented by your reading history. You’ve changed. Making recommendations based on books you read twenty years ago might produce good books for you, now. But probably not.
What aspects of me and my context affect the value of a book?
First, what are my fantasies? Some of my friends have sci-fi fantasies. They love the idea of living on a space ship and landing on planets and fighting aliens and using advanced technology and all that bilge. That fantasy life appeals to them. Whereas I love the world of P.G. Wodehouse. The gentleman’s life, the flitting from manor to manor, the purloining of cow creamers to avoid the homicidal fellow guest. I don’t think either world is any more rich or meaningful or worthwhile than the other. It’s just personal taste.
Second, what is new to me? A while ago, I started reading The Little Kingdom. It’s a book about the early history of Apple. But I put it aside quickly. It wasn’t a bad book. I just already knew everything in it because I’ve read many other histories of Apple. This same thing can happen when coming much later to a book that was ahead of its time. It can seem like old hat because it’s already part of your cultural context.
Third, what am I ready for? I’m trying to get better at graphic design. I recently read a book about grid systems. It was pretty good. But I’m not really ready for that level of depth, so the book wasn’t very high value to me. This type of context is perhaps the most powerful. It was what was missing with Hamming and present with Dweck. I think it’s the main difference between learning slowly and learning quickly. Vygotsky called it the Zone of Proximal Development. One of my programming students at Makers, Jasper, a skateboarder, called it the Goldilocks Zone.
Fourth, what am I doing right now? I have a book on my shelves called Game Feel that is about making video games that feel physically good to play. I’m really excited to read it. But I’m holding off because I’m not currently making a game where the focus is on a good feel. If I read it at the moment, I’d retain and adopt a lot less of it than if I were to wait for when I can apply it.
These things helps me make better choices. There is another set of techniques that help me make a book as good as it can be for me, now:
First, skipping sections that aren’t good. This is tricky. Reading is a place. The more you skip, the more it becomes browsing. And browsing is not a place. You want to be in the place.
Second, dropping books that aren’t good. I find this hard because I feel good about finishing lots of books. But dropping bad books means I will be able to read so many more good books in my lifetime. When I drop a book, I try to say, “it’s not me. It’s not the book. It’s just not the book for me, now.” Even this is hard. Not getting very much out of Anna Karenina, supposedly one of the aesthetic and emotional heights of human expression and experience, doesn’t feel great. But, that’s the way it goes.
I made an Apple Shortcut for ChatGPT. I use it on my:
- Apple Watch - “Hey Siri, talk to GPT”.
- Mac - run the shortcut and type into a text box.
- iPhone - talk or type.
You can use this shortcut too!
- Get an OpenAI API key.
- Install the shortcut by visiting this link on your Mac or iPhone.
- Enter your API key.
The API key will remain on your device. Besides talking directly to the OpenAI API, the shortcut runs entirely on your device.
Customize the prompt
You can change the prompt by editing the shortcut in the Shortcuts app on your Mac or iPhone. I find this makes it much more powerful than off-the-shelf wrapper apps like Quora’s Poe.
If OpenAI have granted you access to GPT-4 and you would rather use that than ChatGPT, just change
gpt-4 in the shortcut.
- Code Lauren - An online IDE for beginners. Includes a vm that lets the user run their program forwards or backwards. Watch a demo or try it out.
- Isla - A livecoding interface and programming language for young children.
- Pistol Slut - A platform shooter. Guns, grenades, parallax scrolling, particle effects. The enemies work in teams. I talked about the game at JSConf.
- Empty Black - A puzzle platform shooter. Throw crates, set off bombs, fire missiles, stab with your sword. Featured in Kill Screen, PC Gamer and others.
Building to learn
- Git from the inside out
- A practical introduction to functional programming
- The Fibonacci heap ruins my life
- Mary livecodes Space Invaders
- An intuitive introduction to algorithmic efficiency
- Mary livecodes a drum machine
- Git from the inside out
- Isla: a programming language for children
- Pistol Slut, collision detection, AI, falling in love
I set up my GPT-3 account so I can text with it over SMS. It’s pretty fun.
To build this, I combined Airtable and Twilio. Here’s how it works:
- I text my query to a Twilio phone number. E.g. “What is a good thing to reflect on as I fall asleep?”
- Twilio receives the text and sends a webhook with the query to Airtable.
- Airtable receives the webhook and this triggers an automation.
- The automation stores the query.
- The automation sends the query to the GPT-3 API.
- The automation gets the response from the GPT-3 API.
- The automation stores the response.
- The automation texts the response back to me.
Airtable serves two purposes.
First, it sends the query to the GPT-3 API.
Second, it provides a way to store queries and responses, which allows it to build up context in an exchange. For example, imagine I send this initial message to GPT-3:
The following is a conversation with an AI movie buff.
The movie buff has excellent taste in movies and is
great at recommending obscure but high quality movies.
Human: Hello, can you recommend me a movie?
AI: Sure, how about Hoop Dreams?
Human: I loved that. Can you recommend me a movie like it?
It replied with:
Sure, how about Beautiful Girls.
...Human: I actually didn't like that movie at all. Can you
recommend me another?
AI: Sure, how about Boyhood?
...Human: I did like that one. I really loved Drinking
Buddies which felt more truthy. Can you recommend a movie
...s are what create the context. GPT-3 only operates based on your query. It has no memory of what you sent it previously. To retain context, each query you send must recapitulate earlier messages.
So, in step 5 above, Airtable gathers up all earlier consecutive queries that start with
..., plus one more (the query that started the exchange e.g. “The following [etc]”), plus the intervening replies from GPT-3. It sends this whole chunk to GPT-3 as a query.
This enables you to steer the algorithm towards more and more useful responses.
I was interviewed on the Future of Coding podcast. It was a really fun conversation. We talked about:
- My work at Airtable helping build tools for non-programmers to make software to do their work.
- Making software without writing code.
- GameMaker, an amazing environment for creating games with minimal code. It has been used to make killers like Nuclear Throne, Hyper Light Drifter and the first version of Spelunky.
- UI design lessons from games like Into the Breach and The Witness.
- Code Lauren and Isla, my past attempts at making accessible programming environments and how my goals of learning to write compilers conflicted with the tools’ goals of making it easier for beginner programmers to build software.
I wanted to get a better intuition for exponential growth. So I made this exponential explorer.
It lets me directly manipulate the starting amount, growth rate and number of periods of a graphed exponential.
I can create multiple graphs and overlay them or compare them side by side to see the relative effects of the different factors.
I can create a set of graphs and share a link to illustrate a property of exponentials. For example: in this exponential, nothing happens for half the periods, then it goes off like a rocketship.
Use Step to get a more precise understanding of how code executes.
You see a code listing. You click on the part of the code that you think will execute next. Then you click on the part of the code that you think will execute after that. And so on.
This is just a proof of concept. You can’t enter your own code, but I plan to change that.
My new talk. No maths, no code, no slides.