(Come see more talks at Deconstruct 2018: registration is open!)
(Editor's note: transcripts don't do talks justice. This transcript is useful for searching and reference, but we recommend watching the video rather than reading the transcript alone! For a reader of typical speed, reading this will take 15% less time than watching the video, but you'll miss out on body language and the speaker's slides!)
All right, can you guys hear me OK? Check? Cool.
Since Gary brought all of us here together, I thought it would be appropriate to begin with a pearl of wisdom from him. "Progammers-- good at building machines with 17 meta knobs that turn the 90 underlying knobs. Bad at asking, 'why are there so many knobs?'" My talk today is about knobs, and I'm going to talk about two themes. One is if you're making a machine, how do you choose the knobs on your machine? And then, once you have those knobs, how do you communicate those knobs to the people, using the machine that you're making? And we're going to look at this through two different case studies. The first case study will be about hardware, and the second one will be about software, OK? Cool.
Case study number one, hardware I wanted to talk about probably one of the oldest pieces of hardware that humans have had, namely the saw. So the Egyptians had the saw in the 31st century, BC, and the original model of the saw was very simple. There were very few knobs at all on the saw. And over time, people started getting ideas, they were like, OK well, copper's nice, but eventually we figured out how to use iron and make different materials and things like that, we started adding more features to the saw. So this is a woodcut from the 1800s, and this shows a two man saw, known colloquially as a "misery whip." And you can, see it's a little more advanced. There's a second handle for a second person to use, and it comes with this pit that you can stand in when you're ripping a huge tree. And this is well and good, probably a lot of the buildings in this area were made out of lumber from saws like this.
And then, in the 1900s, after the invention of the electric motor, someone had a very bright idea of attaching the saw blade to a motor and putting a handle on it. So this is the first Skil saw, this was from 1924. And then, you can see there's more stuff going on here, and that sort of leads us to where we are today. Now this is a saw that I happen to own, this is a magnesium sidewinder Skil saw. And you see, there's a lot of knobs on here. So there's this blade and we have a blade guard and there's this trigger and there's like some markings on the front, you can see there's like a protractor on there and everything. So there's a bunch of stuff on this.
And the question that I have is, is this too many knobs? If you think about all the things that a modern Skil saw can do, you might wonder, OK, there are all these knobs, but can we do better? Can we remove some of these knobs? Or can we accomplish the same kinds of things with fewer moving parts? And there's a lot of different ways that you could try and tackle this problem, and think about this as a design problem. And one approach that I really like comes from a paper by Daniel Jackson, it's called "Towards the Theory of Conceptual Design for Software." And the very high level idea in this paper is that what you should do, if you're making something, is you should list out all of the knobs that you have, what he calls concepts. And try and match those concepts up with the purposes that those concepts are trying to address.
So in the case of the Skill saw, we can do this, we can start looking at all the pieces. We can say, well, there's a saw blade, and the purpose of that is to cut lumber. And there's a blade guard, and the purpose of that is to reduce the risk of you cutting yourself. There's actually, on modern Skil saws, there's a clutch, so where you mount the blade to the motor, there's actually little clutch in there, so that if you're sawing through some material, and the blade hits a knot in the wood, or if you turn it sideways, or whatever, the blade binds for some reason, the clutch will release the blade from the motor, and that's to keep the saw itself from starting to spin and flying out of your hands. And there's a trigger, so you can turn it on and off, there's this groove, so you can follow a line, there's all these knobs, right?
And what's interesting to me, is that if you actually list out the purposes for all of the knobs on this, there's really only one purpose that's the same purpose that you would buy a saw for, namely to cut lumber. You don't go out and buy a saw because you want a blade guard or a clutch, these are extra things, and it makes sense why they're there, but it's not why you bought the saw in the first place. And once you realize that, once you list it out like this and start to think about it, again, it makes you wonder, well, less is more, could we get rid of some of these things while still retaining the original purpose of this machine? And I want to propose a hypothetical to you, to of try and answer this question, how you could design, maybe, a better saw with fewer knobs.
So imagine you had this awesome blue crystal that's kind of pointy. And this pointy crystal has this amazing property, where it interacts with lumber in such a way that if you touch the point to some lumber, it'll split that lumber very neatly into two pieces. So that's our new material, and if we go through this exercise again, you can say, OK well, we have this pointy crystal, it replaces the saw blade, and it cuts lumber, that's great. Now we don't really need the blade guard, because it only has this property with lumber.
As you can see, you can just hold this thing, so you're not going to cut yourself with it. You don't need the clutch, because nothing is moving. You don't need the trigger, because it doesn't turn on or off, and it's just this awesome blue crystal. You don't need any of this stuff. You don't need the groove, because you can-- you don't even need to mark your work anymore, you can take your straight edge, you can take your crystal, like a pencil, right, and just cut your stuff in half.
So to answer this question, can we do better? Yes, this crystal is way better, because there are fewer knobs. And it lets you do all the things that you would do with a Skil saw, without having to learn about all this extra stuff. And you might say, well OK, this is great, Kevin, but this is kind of just this dumb, imaginary thing, there there's no material that has this property. And you might be right. I'm not an expert on crystals and lumber. But it makes you wonder, what if we could make this crystal? What if we could work in some domain where we had absolute control and we could specify, in precise detail, exactly how one thing would interact with another thing?
And that brings me to my second case study, which is software. And the software that I want to talk about is a project that my business partner and I have been working on for a while. We used to do a lot of work on the web, and we made a lot of apps and designs and things like that. And we really wanted a graphic design tool that would allow us to explore our designs in a responsive way. So instead of kind of using Photoshop to draw something, we wanted to have a tool where we could visually draw stuff, but then we could also say how does this work on a small-- like a watch, and how does this work on an iPhone, and how is this work on the iPhone big and tall, and all this different stuff.
So we spent about a year and a half making a prototype of this tool, and then we made one of those very earnest looking-into-the-camera videos, and put it on Kickstarter. And we got about 1,000 backers, which is really great. So we put all of them in this little forum. If you ever do a Kickstarter, I highly recommend that you put them all in this private forum, because then you can hang out with everyone and work with them, and then all the randos are still on Twitter, and they're over there, and you can hang out with your friends over here. And so we did this, and I remember during this process, talking with everyone about this tool, and how they're using it and stuff. There was this one designer, and he opened up this bug report. And he opened up this bug report about margins and padding, and he was basically saying, hey, these margins aren't working, I'm putting them in and it's not doing what it should. And it's a bug report, so I jump in, and I put on my developer hat, and I'm like, well actually, the margins in the padding add up in this, so it's really correct, what it's doing. And we go back and forth, and he's just like really confused. And I remember he says to me, he's like, hey, this is incredibly frustrating. I feel like I'm stupid, because what I'm trying to explain is wasting your time, because your tool works the way that you think it should.
And this really stuck with me, because this happened, and I have two options here. One option is to say, well this is just some ding-dong designer dude, and he can't wrap his head around margins and padding, and that's just too bad. And to be clear, if you choose that option, it means you're an asshole. So my partner and I were like, OK, this is not good. We realized we are making this thing, we are making this machine, and so it's our responsibility to design and communicate the right conceptual model. We put these knobs in there, so that's on us, and we need to really step back and think about that. Are these the right knobs, are we communicating them correctly, and so on and so forth.
It's interesting, because when we started, we're both had done all this work on the web, and we'd very much internalized these ideas of margins and padding, which are fundamental concepts in CSS. And it never occurred to us to question them, we were just like, yeah, we want a layout engine, so like we're going to have to have margins, cool. And then after this designer raised his bug report, it really got us thinking about, well, what are margins and padding, what are they really for, what's going on? So we went through this exercise, just like with the Skil saw, we said OK, we have these two concepts, margins and padding, but what are they actually for? And I try to answer this question the same way answer any question about computers, which is to ask Google. And Google said the CSS margin properties are used to generate space. And the CSS padding properties are used to generate space. And we're like, OK cool. We've got our two things. We're controlling-- we have these two knobs, they both, I guess, control spacing. This is neat. And for those of you who are not familiar with CSS, let me just walk through a quick example, so you know what I'm talking about.
So say you have this orange, this giant orange box, and it's inside this parent container. And if you see this, you wonder well, what's happening? Like why is the orange box where it is? And it could be two different things. It could be that this orange box has some margin, and that's what's positioned it where it is. Or it could be that the parent has padding, and that's why it is where it is. And it could actually be both. So now you have these two invisible things that add up to position it where it is. OK, I can see now, we've like stepped back, we're like, OK, this guy is reasonable intelligent, this person who brought up this issue. It is kind of confusing that we have these two things.
And I was thinking about it some more, and I've realized, of course, there's a whole other thing that controls space in CSS, called positioning, or absolute positioning. So in that case, if you have this, it could be that there's no margins and no padding, but you're like, oh, I've just positioned this child absolutely to be 50 pixels from the left. And of course, because we got these three knobs, they all actually interact with each other, so it could be that you have a left and a margin, and you also have padding, but it doesn't take effect on absolute stuff, because reasons. Yeah, this is confusing. And at least-- I mean, you might step back and think, OK, well these are three things, the sort of historical reasons, but at least we have these three knobs, they all control space. At least we can do all the things that we want to do with these three knobs, right?
My friend. Have you ever tried to center something in CSS? This is a very hard problem. And you might say, well, if you know the size of the parent, you know the size of a child, you can do the math yourself and say, well, I'm going to position it here. But if someone takes their phone and they flip it sideways, and now it's wider, and then your thing is not centered anymore. And from the standpoint of a lot of front end developers and users of CSS, this is basically an open research question. You can tell, because I tried to look this up on Stack Overflow, so this is the question, how to horizontally center or a div in another div. And you can see, if you zoom in here, it was first asked 8 and 1/2 years ago. It's been viewed almost three million times, and the last answer was 10 days ago. So we're still working on this problem.
But the powers that be, the browser vendors and the W3C and everyone, they realized, OK, this is a problem, people want to center their stuff. What are we going to do? They decided to add this other knob. It's called Flexbox, which is actually pretty good, but it's a whole new set of knobs, where you add these properties to the parent, and now you can finally center your things. But now we have these four knobs that all do the same thing. Flexbox is even worse, actually, because margins and padding and positioning, they use words like top and left, which makes sense to normal humans, but then Flexbox has all these other weird property names, like align, self, and just-- you know, and it's like, what is going on here? We have too many knobs, right? We got to get rid of some of these knobs, this is what we've realized. This designer was right, this is really confusing. Can we do better?
And we sat back and thought about this, and we realized, at the end of the day, when you're thinking about spacing, this is-- you're always going to have the situation. You're going to have your thing, there's going to be some space before it, and some space after it, and that's it. You can't get-- as far as I know, you can not get any simpler than this. And so we're like, OK, let's get rid of margins and padding and positioning, and all this stuff in our little design tool, and just replace it with the concept of spacing, and then that's going to control spacing. And let's just see how far we can get with this.
So we did that. But we still have this problem about centering. And we're like, well, how are we going to solve this? We thought about it a lot. We realized when you want to center something, really what you're saying, you're trying to make this relationship, you're saying the space before the thing is equal to the space after the thing. You don't care if that's 17 pixels or 37 pixels or whatever, you just want them to be equal. Then when you start thinking about stuff in this relational way, there's a bunch of other designs that you might want to make as a graphic designer. You might want to say, I want twice as much space before as after. Or I might want to divide this thing in two, and have the first half be in whitespace, and the second half be this child. So there are all these relational things that you might want to express. And you might think, OK, well cool, this is when we're going to add a linear constraint solver to our tool, because obviously, you want to make these relations and everything-- it's like, no, no, no. You don't want to do that, OK? Because people are coming from Photoshop, and if we're telling them that their matrix is not invertible because of too many constraints, it's not going to be good, that's way too many knobs.
So we're like, how can we solve this need within the existing concept that we have? And we realized we could do that if we just tweaked it a little bit. So we decided to introduce this new unit called stretch. And the idea of that unit is it'll just-- you can use it to just distribute any leftover space along a certain axis. So if you want to center something, you could say, I want one stretch before and one stretch after, and then the layout engine will be like, OK well, here is the size of the child, and here is the size of the parent, and here is this leftover space, and so I'll put equal amounts before and after, and now your thing is centered. And you can do all the things that I mentioned earlier. So you could say I have twice as much space before as after. And because it's just this unit, it fits in with the existing stuff that you learned already. You can say I want 20 pixels before, and then the rest of it, I want half of it to be my little child, and the second half to be whitespace.
And we were pretty happy with this, and we realized, as we started playing with this idea, that all of these knobs that CSS Flexbox introduced, we could express using this idea of the spacing unit. So you can use it to control alignment and justification, and you can do things that are actually still very hard to do with plain Flexbox, and it's this general thing that addresses all of these problems. So once we realized this, we were very happy with the situation. So to recap, that was how you choose knobs as a case study. And the first step, and this is really the most important step, is to just realize you have too many knobs. And we spent a year and a half building this whole thing, and it never even occurred to us to question CSS. We're like, well yeah, they have these knobs, and this is the thing-- but once this one designer was like, this is really confusing, what's going on, we were like, oh yeah, this is really confusing, there's a lot here. And once we did that, it let us step back and think about it more, go through this exercise of matching those knobs to what they're actually supposed to do, and then try and simplify that. So that's the first theme that I wanted to talk to you about, which was how to choose your knobs on your machine.
And the second one is how do you actually communicate those knobs to people? If you're making some system, you step back, you think about it, you make these choices, you make the right knobs, and you're happy with your knobs. But you still need to communicate it to the people using your machine. They need to internalize what those knobs are and what they do and how they can use them to accomplish whatever task they're trying to accomplish with your machine. And I want to talk about this with three principles that you can take and hopefully use in your own work. The first one is-- this is actually a technical term, called information at the point of need. So if you Google this term, you'll find lots of great examples and other things. But the big idea here is that-- let's be real, people are not going to read your manual. They are they're not going to read it. So if they need to know something to use your tool, you need to show it to them, right when they need to know it. And in our case, because we're making this very visual layout tool, most all of the knobs, we can actually show them visually. So we spend a lot of time, after we did this layout engine, making these heads up displays, so it would just show you the values of all the spacing and sizing, right in context when you're messing with your design. So it's not buried inside your little property inspector or whatever, just as soon as you start playing with stuff, it's going to be like, hey, here are all the knobs that are in play right now, and this is why your design looks the way it does.
Now the next principle that we tried to follow a lot is preferring recognition over recall. And between my partner Ryan and I, we like to call this the Denny's Menu Principle. So I don't know how many of you have been to Denny's, but it's an American diner chain, and most of the locations are open 24 hours a day. And what's great about the menu at Denny's, is that it is completely usable, even if, for whatever reason, you are functionally illiterate. So this is a page from the Denny's menu, and you can see there's a bunch of text, there's like eight paragraphs of text in the middle, but that doesn't really matter, because 2/3 of the page is all eight of these sizzlin' skillets. So you don't have to do any reading, you just look at the one that you want, and you can point at it, and then you can order it.
This is not a mistake. The people at Denny's know what they're doing. So we wanted to use that principle in our tool to communicate all this semantics and the capabilities and the knobs underneath there. So this is an example of the control panel on the side of how you layout things in the system. And what we did, you can see, there's these three buttons beneath both the horizontal and vertical, and the buttons are just these things that you can recognize that will do, hopefully, what you want them to do. So if you're like, I want to align my thing to the left, you can just click on this button, or if you want to center it, you just click on this other button. And these buttons, they don't twiddle any hidden state or set any properties, all they do is they put in the values in the inputs above. But if you have it internalized, like what this stretch unit is, or how you're supposed to think about things, or express stuff, you can just see these examples, and you click on them, and it does the thing that you want. And then, hopefully, if you're paying attention, you're just like, oh well, all it did was set this number in here, it kind of teaches you what's going on.
And the final thing that we did to communicate this model, it might seem a little strange, but we actually spent a lot of time introducing errors into the system. I guess the best way to motivate why errors are helpful is to imagine situations where you don't have errors, which brings me back to CSS. In CSS, you can use positioning to say, I want this 20 pixel wide thing to be 10 pixels from the left. Or you can say I want it to be 10 pixels from the right. And if you resize this thing, it's going to stay pinned 10 pixels there. And you can even say I want it to be 10 pixels from the left, and 10 pixels from the right, and if you resize it, it's going to adjust the width to match.
So the question I have is, what happens when you specify all three? And if you like gambling, this is a great time to turn to your neighbor and ask what they think, and place a bet. What you think is going to happen when you specify all three of these things. Because to be clear, if this parent box is 100 pixels wide, you're saying I want a 20 pixel thing to be 10 pixels from the left and 10 pixels from the right. This is impossible, like mathematically. You cannot do this. But interestingly, CSS will not raise an error. It will do something. In some ways, it makes sense for CSS, because browsers have to parse all this garbage on the internet, with broken tags and things that just aren't-- like impossible, it still wants to draw something for you. But if you're trying to build something, if you're trying to internalize how this model works, not having errors is actually very harmful, because you might think that this is a reasonable thing to ask, and you will get away with thinking that, because it'll still draw you a box somewhere. And this is a homework exercise, I don't know what happens here.
In our tool, we have the same problem. So you could specify pixels all along an axis and ask for something impossible, but instead of just doing something, and dropping one of those implicitly, we decided we should just raise an error. So we actually turn whatever you're working on into this little red box with an exclamation point, and if you zoom in here, we give you the error right in the control. And it says hey, something needs to be stretchy here, because this is not going to work. And if that doesn't make sense to you still, you can click on it, and it explains a little more, what's going on. And you can say like, look, you can make the top part stretchy or the bottom part, or the height can be stretchy, but something has to be stretchy here for this to work.
And this, again, it really helps you if you're learning, you're coming into the system-- there's a lot of error-- error messages have such a bad rap, because they're so unhelpful usually. It's like, something went wrong, you were wrong, and then you have one button that's like, OK. So But they don't have to be that way. I wanted to give a shout out about Elm's errors, I was going to talk about that, but I haven't already did all that. It's awesome though, because this is not rocket science to make errors like this. If you're making a compiler, or some other tool, you just have to think about how things might go wrong, and then spend a couple of minutes being an empathetic human being, and just saying, how can we help this person use this thing better?
OK so that's all I wanted to talk about. And I want to close, and just implore you that, if you're building some sort of technology, whatever that technology is, if that's software, if that's hardware, please think of the knobs, OK? You have to choose the right knobs, think about why they're there, what they're actually supposed to do. And then once you've done that, try to think about how you communicate that to the people using your tool. And that way, if they actually understand the capabilities of your tool, they understand what all the knobs do, they're really empowered and they can use it to go on and make great stuff. Thanks.