I've been really interesting in Dan Abramov's Just JavaScript course. The course (so far) takes the approach of treating the rules of JavaScript as natural laws, and a lot of the explanatory effort so far has been about aligning your mental model to those laws (there is a long running idea of the connection between variables and values as 'wires', for example). As it's been introductory so far, it hasn't exposed me to a lot of new thinking, but it has strengthened my understanding of how object properties work. This was not something that tripped me up a lot, but I realized after going through the JJ explanation that it had been weighing on me as I wrote code -- I'd been working around the gaps in my knowledge to an extent and I'd also been actively defending against bugs related to those gaps. So if I wrote code I was unsure about I would save and test it in the middle of writing, versus feeling confident enough to finish out the function I was trying to make. I was surprised how much of a benefit that 'in-world' knowledge of javascript provided. I felt on much surer footing while writing code (even though the new knowledge had very few direct effects on the code I wrote). It was a feeling of comfort, I keep wanting to call the feeling 'being on sure footing'. It wasn't that I could access new places exactly, but I felt a lot more grounded and confident writing the usual stuff, which made writing code a more pleasant experience. It was also like having less drag -- especially as I built a larger app, where accumulated uncertainty kind of weighs you down as you go (some expectation that something is going to break and you're not going to know the reason).
So I"ve been enjoying that experience and also thinking a lot about what it means on the meta-level. Because along with that course, most of my thinking about code lately has been focused on learning more about how a computer itself workers. This really got kickstarted with reading Code: A Hidden History. The idea behind all that, I think, was that these languages are leaky abstractions, and that the only way to feel on truly solid ground would be to really understand it from the ground up. I'm not done with that approach, but it Just JavaScript is causing me to reassess it a bit. Maybe there is no tension between the two projects, it just depends on what you're doing, but it definitely feels like there's something to be productively explored there.
The question is maybe just at what level of abstrac tion do you want to explore things. That seems like the central question for any tool. Closely related to it is what level of primitives do you want to expose to your user (and there is lots of nuance in that, maybe you expose one level of primitives, but there is an escape hatch to let people go even lower-level than that). That is something I want to think about. I want to think about why ithat decision is important, too (what are you ultimately trying to enable)? People to create things (yes)? People to create things where they feel in control (on solid ground) (yes, I think so)? How does this compare to the physical processes people use to create things (like pottery, or paining, where the material has a feel and a resistance to it)? It seems like making a tool is a process of finding the right constraints. The constraints of physical things are so varied (what makes learning painting something people waht to do? learning to play an instrument? Think about the end product versus the feel of the process).
That's something I possibly hadn't articulated before: end product versus the process. Painting and playing an instrument have a long learning curve -- I would imagine motivated by the end product (think of what I could make). What do I want to do with a tool? The end product is the carrot, but I want the process to feel good. Are video games the opposite end of the pole (not quite, they're pretty goal-oriented as well).
Slowing down, but I will throw in that also, always with this stuff, I am thinking of lego and minecraft. About their phenomenal success, their enduring attraction, and why more things aren't in that realm (why not more games that play to those impulses? Is it that people only have room for a few of those things? There's also the Sim- series of games, I suppose, but still it seems underexplored).
What else? Another inspirational part of Just Javascript is that there is still room, giving all the approaches to teaching code, for an approach that (seems) new to me and is effective. It is affirming for my faith in the importance of mental models, and as I think about making my own stuff, and have worries that I'm operating at too basic a level (that all the opportunities for this sort of thing are exhausted) this makes me feel like, no, there's still room, start from the beginning again, don't take things for granted, if something doesn't make sense dig into it more. I should write more about primitives more, I think that level of abstraction you enter into is something I need to think more about.
Rgb is the newest experiment on Constraint Systems, it lets you select different rgb values using key color combinations -- simulating the experience of mixing colors.
Rgb fell out of another project, where I was returning to the grid-based editing of Hex trying to put it together with the sprite-based font editing from Face. With outlining and text, I'd be close to the grid-based paint program useful for creating diagrams. I decided the missing piece was color, and then I got caught up trying to decide the best interface for inputing color. I originally thought I'd use a color palette with a few (8, 16?) colors to be selected, but I wanted to experiment to see if there were more intuitive interaction set-ups -- something more similar to the hex experiment.
I decided to try a method where you use key combos to set the rgb values, one column for red, one column for green, one column for blue. Each column has options for 0, 122 (half), and 255 (full). This lets you do the basic combos, and also get mixes for things like yellow, cyan, and orange.
I used rgb because it corresponds to the colors pixels are made up of in the computer display. In some ways, if I want an intuitive, painterly interface, it would make sense to use a color space that fits better with human perception like HSL. But something I'm narrowing in on with these experiments is what exactly I want to do. I think what I want to do is bridge the gap between the computer in the user in an interesting way. I don't want to build an interface where the user doesn't have to think about what is going on in the computer at all (an approach I associate with Apple). I want to "go with the grain" of what's there. By providing an interface where people can productively collaborate with the computer, while also getting used to some of the lower-level abstractions, I can help them build knowledge that will carry over to the larger computer system and will make them feel more empowered to do other things.
That is the more philosophical motivation. It's also true I think that creative systems just thrive on constraints -- so why not use the constraints that are built into the computer. This makes for a collaborative interface on the part of the user, and it's also an interesting collaborative process for me to develop the interface, choosing which parts to augment of make more forgiving and which parts of the representation to keep laid bare.
The interface also provides a playground. One of the interesting things related to AI and its current limitations, is the question of whether it can really learn without an embodied experience of cause and effect. One of the experiments of constraint systems is how quickly we can adapt to a new system if we have quick and consistent feedback. It's something I've been exploring myself in the computer programs I use -- switching to Linux and using lots of keyboard shortcuts, using a smaller keyboard. I've been surprised at how possible the switch is, though it eased a lot by a consistent set of expectations, and a consistent mental model of how the shortcuts and the system works. I'm interested in creating those experiments in miniature. I'm also interested in the overlap between these ideas and how you learn a videogame or an instrument. I think about the system behind Minecraft a lot. Where you have this set of rules that you can reason about, there's also a lot of eccentricities, but I think the block rule set keeps it grounded. I think about how popular Minecraft is (the most popular game of all time!) how it fits into a human desire to create.
I released Face on Monday. It got more Twitter attention then any of the other Constraint System releases so far. Which feels good! Although I also do notice that there wasn't a lot of direct feedback -- or (what I'd really like to see) people sharing things they made with it -- just likes. I did get some feedback I've been thinking about: that the 'hjkl' direction navigation (borrowed from Vim) is a high barrier to people jumping in.
Why do I use the navigation? Well, first because it is what I use daily, in Vim, in i3wm, and while browsing the web thanks to the Vim plugin. Also since I've switched to the Atreus keyboard, my actual arrow keys are a couple layers deep, making 'hjkl' even more convenient.
Ok, that makes sense, but why not give people not used to it the arrow option? That speaks to a broader design question. I started doing the Constraint Systems stuff directly inspired by 100 Rabbits, specifically Noodle, which is a pretty uncompromising drawing tool (for one thing it starts with a completely blank screen). It drove home to me that you can just do that -- make exactly the tool you want exactly how you want it, and, in 100 Rabbits case, you can even build a community of like-minded people around that tool. This is especially in contrast to when I'm designing something at work and I feel like I have a responsibility: to the team, to the project, to make things accessible to a broader audience.
Closely connected to that is feedback/iteration speed. If I'm building the tool exactly how I want it, then when adding or modifying a feature I simply have to determine if it feels good and makes sense to me. If I start extending the configuration, so that it can be used in ways that I don't, I add overhead, where I have to check new features against both my use and the alternate flow I've added in. (Another option is to make things configurable, which I'd like to explore sometime soon, but I also can't expect configurability to solve all my problems, the vast majority of folks will stick with the defaults.)
Also tied to that, is that I view the constraint systems project as my journey to 'find my own way', something I always have trouble with when giving feedback is if my feedback makes sense for my mental model of the project, but not the person creating it. Sometimes they'll try to satisfy my feedback, but if they aren't on the same page about how it fits in, chances are they'll do something down the line that will clash with my suggestions. Usually I think that I would rather see the fully- formed, fully-developed thing from someone else. I'd rather see a coherent mental model I don't totally align with than a mish-mash.
In fact, I think what is interesting in a lot of the 100 Rabbits projects is to me it often feels like they're coming from an alien logic (Orca especially is like this). That's a big part of the thrill of it. It's like my favorite trope in sci-fi books of how an alien language can unlock new modes of thought.
But what comes with this is a big learning curve. And I think that's what I need to think about more seriously with the experiments. Because if I want people to drop in and create and share, that unfamiliar confrontation is going to cause many to bounce off. I think in the back of my head I'm still imagining Constraint Systems building in to some sort of app that combines writing, drawing, diagramming and maybe image editing, and if you're going to go through all that you may be more willing to perservere through an unfamiliar control scheme for a payoff down the line. But if you just see a GIF on twitter and click through... you're less likely to do that.
So I need to think about what I want to do. I also feel like I am doing a slippery slope thing, where I want to make sure I don't chase after every piece of feedback I hear (I've worked on projects I felt were doing that and found it frustrating), but I also shouldn't get too strongly attached to some perceived purity. Because on a basic level what I'm talking about is enabling arrow keys for navigation along with hjkl. Something even Vim, which is not exactly beginner friendly, does. And I think I can go ahead and do that without feeling like I'm really compromising the vision of anything -- especially if I think of it as making it more possible for people to make things, which is my top goal.
It doesn't come without a cost (some part of my brain shouts) though. Even though enabling them is trivial code-wise, I will need to think through how I expose it in the instructions, instead of saying 'j' for down, I'll need to say 'j' or '↓' for down. Which does add some overhead. Probably worth it, though? Trade-offs!
This weekend I finished Face, an editor where you can change both the text and the font. I learned a ton doing it, both about how to use canvas, and about how fonts are traditionally rendered.
Face was made to investigate fonts more. Making it I realized I've always chafed against how limited my control of a font in a design is. You get to choose the font, but then you're locked in. Part of this is because font design is complicated. I don't have the skills to go in and edit an individual letterform so that it better fits in this specific design and also harmonizes with the rest of the font. Fonts are generally constructed in terms of vector shapes -- editing one of those is daunting because so much craft has gone into balancing it.
Face uses a pixel font, where the letters have an 8x16 pixel grid, This makes editing a specific letter, or even several letters manageable. The constraints mean you can understand how a letter works and imagine how your changes could affect it (you can have a reasonably accurate mental model), What you lose is access to all the great expressive work font designers have done. You also lose easy scalability (depending on the pixel density of your screen, in-between sizes can result in blurry pixels). These experiments are trying to really get a feel for those trade-offs, and maybe find some different directions around them. I've been working towards something that has a 1-bit drawing mode combined with text, where the text-sizing is regular and predictable.
In all of this I've been thinking a lot about Minecraft. Minecraft seems to me to be a triumph of an understandable mental model -- for both kids and adults. There is something so freeing about everything in the world being built with the same building blocks you have. And it's been so successful, the desire for that sort of play must be so deep (legos are the obvious antecedent, and still massively popular themselves). And yet it still seems like an underexplored space to me. It seems like a space uniquely suited to computers, since in certain ways computers can reprogram themselves -- they attempt to be nothing more than a possibility space -- at least that's my favorite version of what a computer is. I want to do projects that unlock that feeling.
Rough music purchasing plan:
I've been meaning to switch off Spotify to bandcamp, but unsure about how to start the transition. So I'm planning a system.
I keep listening to Spotify, tracking what I listen to using last.fm. At the end of each month I buy three albums.
Which albums I buy is based on a combination of: what I listen to the most + bias toward active artists (release in the past two years?) + bias towards less popular artists (probably using a threshold of global plays on spotify or last.fm) + available to buy on bandcamp.
Maybe I'll make a script to calculate this for myself.
Using i3wm (a tiling window manager) has caused me to think a lot about how arbitrary our current computer interaction model is.
In some ways a tiling window manager isn't that big of a departure. I was already using a macOS app to do quickly snap a window to sides, or quarters of the screen. But it's a good experience in the power of defaults. The fact that a new window automatically splits the space in half changes my workflow in lots of ways. Probably the clearest is when I'm working on debugging or learning something programming wise. If I need to look up options I open a web browser right alongside, or open a terminal to refer back to another site I worked on. Within a workspace the default action is to "pull up alongside". Closing is quick and easy (partly this is due to a lack of animations). Space seems less physically constrained (less skeuomorphic) in a good way. I can pull up these magic windows and then dispose of them when I'm done. Again, of course none of this is impossible with a non-tiling window manager, but the feel is different. There's stability in the constraints. That stability is a feeling I feel like I'm going to be chasing and trying to pinpoint for a while in the computer interactions I build.
I also love the workspace set-up. You have workspaces 1-9 to start with, and you switch using meta+n. As the wonderfully transparent config file shows, that's actually totally arbitrary and configurable. You can name workspaces -- a lot of people seem to do that. In macOS I had a very specific spatial system of email in the top left workspace, browser in top center, etc. I'm developing some conventions using i3: I tend to try and keep 'work' in 1-5 and us 6-9 for stuff like email, slack, etc. But I've resisted naming and declaring a workspace. The utilitarian number system supports what I was talking about with the splits -- you don't have to carefully consider where your programs go, they're there to work for you. This is also very much supported with how you can transfer a window from one workspace to another (I always think of it as throwing). There's a really satisfying interaction where I'm searching through documentation for an answer, splitting with web browsers and terminals as needed, and I run into a longer read related to the problem. I throw the long read to a middle workspace to read over lunch break or something. I track down the solution to the specific problem, and I unwind the split search -- closing all the windows I no longer need. I'm back to a calm one or two split workspace. If definitely has the feel of pulling out a bunch of books and spreading them out on your desk, then cleaning up afterwards, except much faster. Even though overlapping windows are maybe closer in their functionality to that physical experience (you probably do overlap your books) the tiling feels closer to it in spirit.
I saw one screenshot of someone who had configured their workspaces to be in roman numerals, which is both very unnecessary and because of that sort of wonderful
So what do I do with this info, besides enjoying using my new set-up. Obviously I want to put this into the things I make somehow. Probably I will do some splitting experiments for some of the constraint systems stuff. But more than that I think it's the excitement that there is a lot of uncharted ground here. (This fits in also with just reading about Linux/Unix history, feeling how arbitrary the conventions are, how much they were developed for different situations.)
It's been a few weeks of using and configuring Linux for my work computer and I want to document some of what I've been doing and how it has been affecting how I think about things.
I was initially inspired by @neauoire's posts about their switch to elementaryOS. That made it feel within reach. I tried it on an office Thinkpad and was surprised how easy the usb-stick based installation was. Elementary seemed well put together, but I realized using it that I have a lot of complaints about how macOS handles shortcuts. I didn't just want those shortcuts replicated. I figured maybe I'd get there over time, customizing and tinkering with it once and a while. (I also didn't totally know what I wanted in terms of shortcuts/set-up, just... something else.)
Adam suggested I look into i3wm, a tiling window manager. I found a fantastic tutorial on getting started. I think watching this was the point where I realized this was really viable.
I went back and installed ubuntu so I could follow the tutorial exactly. I'd like to switch off ubuntu (maybe to Arch or nixOS) but I'm holding back for now. The nice thing about ubuntu is that when I get stuck doing things on the command line there's usually a totally functional GUI option I can use to. I'd like to move to the command line as much as possible, but it's nice to have an escape hatch in case I don't want to get deep on, say, connecting bluetooth headphones right now.
If there's one thing I've done a lot in my career, it's jumping into technologies I don't understand well and figuring out how to wrestle out what I want from it. It's interesting to try and reflect on what the strategies I use are. One thing I think I've definitely learned is one-thing-at-a-time: that's the idea behind using ubuntu for now. It's enough to get my head around i3wm, I can switch the distro later (it's still a temptation I have to actively resist, though). At the same time, I know I'm motivated by seeing tangible results. So if I want to get the current song displayed on my status bar, I don't feel I need to understand how to do that from scratch. I'll get what looks like the most popular bar (polybar) and find a package and paste a config to get it going. Balancing that mix of getting things I'm excited about running and also going step-by-step is the main meta-task in managing my learning. I think I've definitely developed an intuitive feel for how much I can paste in to feel excited and how much I need to actually understand in order to feel like I still have a handle on the system (compartmentalizing things is also a big part of this, I can have something I don't understand running if I can chunk it as a conceptual unit -- I can always investigate how it works later).
I've been surprised how relatively smoothly this has gone. I think part of it is Linux config is less complicated than I thought, mostly due to people's willingness to share knowledge. But also I've been prepared in various ways. There's using vim, which has gotten me used to a mode of navigation, which i3wm shares. I think that is actually the main draw for me, having this composable system of movement that carries over from vim to the window manager. I also think getting used to npm prepared me better for installing packages (I know the influence goes the other way, but for me it was npm first). I still definitely want to understand more about the mechanics behind packages, and how that system has evolved.
At the same time I've been surprised how radical it feels to extend the customization options I'm used to being able to apply to the web out to other applications. To have nothing on the screen that I "just have to live with". It feels empowering, and it makes more sense to me why some people are as adamant about Linux as they are. It's exciting! But that excitement is tampered by the knowledge that it's definitely a luxury of time and tech that I'm able to get these deep into config. So I don't want to declare it the answer to all things. But I am surprised how exciting of an experience it has turned out to be.
Related to that, an idea I've been thinking about a lot lately as a model of being in the world/influencing others is: paths. Sometimes I think I'm too caught up trying to think of something completely unique to put forward, rather than engaging with others. Maybe a better way to think about it is that I'm helping to tread a path that others have already made. Here I'm following a path of all the work that's gone into Linux and the tools I'm configuring, and also what seems like a new willingness among designer-devs to move off of mac. Sharing my process of moving, and the excitement I'm currently feeling, can help other people decide to make the jump. Then rather than feeling like I should be coming up with something completely new, I just need to make sure the things I'm doing and sharing are treading a path that I think more people should travel on (or even have the option to travel on). I feel good about that with this project so far.
English text is read from left to right.
Text is 1-dimensional. The simplest representation is an unbroken horizontal line. Horizontal reading is uncomfortable though, so we wrap text. The wrapping is presentational only, it has no semantic meaning.
A paragraph is the first spacing-based presentational layer that goes on top of writing. (In CSS a paragraph is when you can start making some real spacing choices.) It is often an indent or an empty line.
Headings are the main tool for establishing hierarchy in an HTML or markdown document. There are six levels. You're only supposed to go down one level at a time. The sections that come after a heading are usually assumed to belong to that heading, though rarely is the code set up this way (the paragraphs are siblings to the heading, not nested within them).
Headings should stand out from paragraph text and they should show their position in the hierarchy. Sometimes I try really hard to think of a bulletproof style hierarchy for the six heading levels.
One of the toughest things about showing hierarchy with headings is that rarely are all your headings on the screen at the same time, so you need to be able to see an H4 in isolation and be able to tell it from an H2 and an H5. It's pretty hard to do this just with sizing. But more explicit methods are often distracting.
Some of the text styling methods you could use for headings are: bold, italic, all-caps, and underline. Underline is not a great option on the internet because of its association with links.
My last attempt at using text styles (no sizing adjustments) to cover all six headings was:
That went OK, but I ended up just switching over to sizing because it was too noisy. It's frustrating that it doesn't really follow a logical progression (why is 'bold' higher than 'bold, italic'? because if you actually try it out going the other way it feels weird). I think part of it is that bold is much more jarring visually than italic or caps, so it's difficult to harmonize them all across six steps.
You do have some other spacing options you could use. Like space before or after a header. I think this can get you a little ways (more space around h2 then h3) but, again, it's difficult to set up a progression that isn't extreme on either the H1 or the H6 end.
One thing I always want to go to is indentation. This probably comes from being used to indentation in code, where it is the main hierarchy signal. The main obstacle I see is just that screen size is limited (especially on a phone). It's going to be annoying if you're only getting to see a few words a line because you're in the middle of an H4 section. Indentation could also be challenging to code up, since paragraphs aren't actually nested under headings. You'd have to run some code to do the structured nesting. Definitely possible, but you're adding in more complexity. I'd still like to try something with indentation sometime. Maybe the indentation can be signaled by a line, so you're not losing as much reading space in the deeper subheadings. Indentation seems like the cleanest symbolically.
I'm working on a new build system for our Fast Forward reports. Previously, we have been writing in Asciidoc. That gets converted to HTML via Pandoc and inserted into a Django template. It works partly through an Asciidoc configuration file with a bunch of trial-and-error-based hacks that I never felt comfortable with. I have long wanted to revamp this but it's taken me a while to figure out exactly what I wanted to do.
So far, in the new system we write in markdown. The report gets built using node and a markdown renderer called markdown-it. Markdown-it had enough plugins/rendering flexibility to get almost all the features we regularly used in Asciidoc (table of contents, figure captions, an info box). The output is much cleaner and I understand the system much better (it's still on my list to understand the markdown-it configuration options better, though).
The markdown render gets put together with HTML and and CSS via a node build file. The process of manipulating (reading, writing, moving) files through a build script is new to me, and it feels great to have that control. I discovered the techniques looking at build processes for Next.js static blogs. The file has gotten messy as I've added more CSS and some javscript. But it still feels great to know exactly the relationship between the code going in and the code generated. I also get to carry over some of the style stuff I've built up from React, where I set a unit for line-height and then can use that for spacing math in both the CSS and the element style options.
My end goal for this is for us to be able to publish research and feel very confident in the presentation. Another big part of this is communicating the available content styles to the rest of the team. A constrained and understood style space is going to ensure there are no rendering surprises. It will also make it easier for everyone to write. I often think back to the title of the article "When I sit down at my text editor I feel calm". That is a big part of the goal. That everyone can sit down and do the work of thinking and writing and feel confident in their tools. Having the tools be understandable (so the user can maintain a mental model of what's going to happen in their head, and feel confindent about it) is, I think, a key part of reaching that feeling.
This is an area I've returned to again and again in my work. I'm thinking about whether and how it could be turned into a career. What is it exactly? Is it just building a CMS? I think what I want to make are content systems. So content strategy is in there. And I also want to build the (simple) tools. And then part of the tool constraints should be tied to the branding, which I'd also like to develop. So that's a lot! Or would I like to make the system that lets other people make these systems?
I have an idea for a writing system where I just describe the things around me (basically like doing a sketch from life everyday but for writing: "My computer is sitting on a brown, wooden table. The table is covered in tan scratches, mostly in the middle and around the edges. I have a small coffee in a cup on a saucer. The coffee is a shade of tan in-between the colors of the scratches and the table."). I wonder what that interface and presentation should look like? Should I also actually draw the scene, and present the sketch along with the words? That seems like an interesting project but the drawing would make the writing somewhat irrelevant.
The ambitious idea of for the observation-write presentation is to use some of the ASCII art experiments I've done, and take a picture of the scene, that then gets rendered using only the letters from the description. I think this is a cool idea, but it might have too many fiddly aspects to start with.
More presentation ideas:
Of those, I think something that represents the different scale of the writing sounds the most promising. It has the feel of a presentation conceit with a meaningful connection to the content, where I'd actually be interested in getting a feel for how much I describe small stuff versus large stuff (compared to time of day or location, which for me would be pretty same-y day-to-day). But what is the way to present that that is noticeable but not overwhelming? Something with bigger and smaller font-size is what I first think of. Hard to that do without being really distracting, though. It would be cool to have a 3d interface where the text is positioned in space. And then maybe the closer stuff could actually be writing positioned closer to the viewer. But I also want the entries to be arranged reversed-chronologically, how do I merge those two overlapping organization systems?