This is the blog part

February 2023
  February 2
    Twitter is cutting off access to Drummer soon. I already have a complete backup, with revisions, of my Drummer files because I use Roady to sync them to GitHub. But I still used Drummer's Tools → Download my files command just in case. I wish I could help Dave Winer with the transition, but I don't think there's anything I can do beyond just letting him do his thing. I am glad he wants to keep Drummer running!
    Sometimes I run the roomba just because it makes it seem like there's another live thing in my apartment, and that is science fiction as fuck.
    You start with no cassette decks, and you can't play any tapes. And then you have five cassette decks, but you still can't play any tapes. Everything is broken, always. Sometimes it's because cassette decks are full of super-complicated parts, all 40 years old, wearing out. This is also how software development is, all the time. Something is always broken, and you have to fix it, before you can get to the good parts. Sometimes it's bugs. Sometimes it's billionaires scraping the friction from the gears of their money creation machines, optimizing away all the stupid extra edge cases, what are those parts and people for anyway, you do not need those, because they do not make me money. Most people are not like that. We do not break things on purpose, for thousands and thousands of other people, just for our own gain. There is a type of person who will do this in a heartbeat, and say you are stupid not to do it that way, too.
January 2023
  January 5
    The best part about AI is that it is insane, and stupid.
  January 4
    Introducing Dababdra. You never knew you needed it. But now you do.
  January 2
    Recording the new year
      (11 min read)
      A cassette recording is not a copy. You can make an exact copy of a digital file, and each time you load that file you will get the exact same series of bytes. A cassette recording is literally a recording of a specific event. It is a record of reality, as it exists at that moment. It's the intersection of the audio signal, measured by a specific source device such as a Super Audio CD player, and captured by imposing magnetic flux onto a particular tape by a particular cassette deck. The recording is a captured performance of specific set of conditions, each of which contributes to the final sound.
      Every cassette recording is literally unique in the universe. The cassette deck is a physical device, and mechanical devices are not perfect. Tape heads, capstans and pinch rollers get dirty. The motors spin as consistently as possible, but there is always wow and flutter. As a painter may work on a stretched canvas, or paper, or cardboard, the tape itself is also a physical medium. Each has its own characteristics, such as how much signal it can take, how much noise the tape itself provides, how much bias it takes to properly orient the tiny magnetic particles.
      The final sound, at playback, is another performance, created in real time by a physical device, a cassette deck which measures the magnetic flux on the tape. This signal is amplified, and used to drive a preamplifier, amplifier, and then speakers or headphones. Every time you listen to a cassette, it is a specific, particular, unique, individual experience. A performance, a rendition of a specific reality, created in real time.
      This weekend I have been making recordings from my NAD 6300 Monitor Series Cassette Deck. I spent the past several weeks aligning this deck. Most of the adjustments you make are related to recording, and the pots and variable capacitors are extremely sensitive to the smallest movements. Sometimes you're just applying pressure, rather than turning. And once you've made that feather touch, you record a test signal for ten seconds, adjust the test signal to a higher frequency, record another ten seconds. Then you rewind the tape, and play it back.
      Measurements are taken from test points at the input to the Dolby circuitry, at the minimum levels you can record. Input around 6 mV results in a measurement of around 40 mV. You watch values change on the multimeter, which you have set to maximum digits, and adjust the meter's rate so it gets a steady value on the first frequency, and set that as your zero dB reference. Then you watch for the change in voltage at the higher frequency. You want the difference to be as small as possible. To be in spec, it should be within 0.5 dB. If it is not, make the adjustment again, and redo the recording.
      Each individual nudge-record-adjust-frequency-measure cycle takes a minute or so. There are more than two dozen variable resistors and tuning filters to be adjusted, and it can easily take a dozen or more attempts before you get one into spec. These are resonant circuits, which means they have a specific point at which they are in tune, and you can't just turn a pot until it reaches maximum. Maximum will be somewhere in between the extremes, and that point will shift as you tune the other parts of the circuit. Some of the steps affect adjustments made in previous steps, so you go back and fine-tune those, another half-dozen more adjustments to something you've already tuned.
      If you are patient, you can get all the adjustments to within the specifications listed in the service manual, and your deck will perform as if it were new, fresh from the factory. In that condition, the NAD 6300 is famous for being able to make some of the finest recordings possible. If you are servicing someone else's deck, that's where you stop. It's performing to spec.
      But for your personal deck, you can be extremely patient. You can get all those 0.5 dB differences down to 0.05 dB, or even less, and your recordings will be even better. (And if you're just learning, as I have been, you will do the entire sequence multiple times, just to be sure you understand what you are doing, and to ensure that repeated measurements let you know for a fact that you got it as close as is physically possible, and that you didn't stop just because you got tired or bored.)
      The reason there are so many adjustments to make is that, in addition to having do do everything twice, once for the left channel, and once for the right, you have to do everything three more times, because there are three main types of cassette tape, and multiple adjustments to make for each of those.
      To ensure that the magnetic particles, embedded within the thin, stretchy plastic carrier tape, take the maximum signal, the recording circuitry will add a high-frequency component to the signal. This high-frequency energy, outside the range of human hearing, is bias, which I think of as a way of overexciting the particles so they settle down more easily into the pattern we want. It establishes a baseline of energy, atop which the musical fluctuations ride.
      There are three main types of cassette tape. Type I is "normal", type II is "chrome" and type IV is "metal". (Type III exists, but is rare.) They differ mostly in the kinds of particles embedded on the tape, and each requires a different amount of bias, and therefore a separate set of adjustments to the cassette deck. There is not just one "type I" tape, of course, there are different brands, such as TDK and Maxell. Each manufacturer made several variants, aimed at specific levels of performance and price. So a TDK D is different from a TDK AD, and differs from a Maxell UR, or Maxell UD XL-I, even though they're all type I tapes. Even the same type, from the same brand, can vary depending on when it was manufactured.
      But you have to align your deck to an actual, physical, cassette, so you have to select one brand, and one formulation from that brand. Your deck will be aligned perfectly to record on that kind of tape. But because you will want to record on other brands and formulations, the NAD 6300 has a fine bias adjust knob on the front. If you're recording on the tape you used to align the deck, you leave it alone. But if you're recording on some other type of tape, you carefully adjust it for accurate treble reproduction.
      I have signal generators, distortion analyzers, and spectrum analyzers, so eventually I'll get around to doing it right. But for now I am doing this part by ear. The other, critical, adjustment you make by ear is setting the recording level. This can be done with lab equipment, but we don't listen to test signals.
      Sources vary in loudness, musical dynamics, high-frequency energy and bass. Tapes vary in their ability to take the magnetic flux. Some tapes can be recorded hotter before saturation distortion becomes audible. You want to record the maximum possible signal the tape will take, because the tape itself has some noise, a hiss, you can hear all by itself. The higher the signal you can put onto the tape, the louder the quietest parts of the music, the less hiss you can hear.
      In addition to fine-tuning the bias circuitry during align meant, and the front-panel fine bias adjust, the NAD 6300 has two more features designed to maximize recording volume: HX Pro, which was an improvement to a Dolby design made by Bang & Olufsen, and DynEQ, which came from Tandberg. There aren't many decks made with both, which is one reason the NAD 6300 is unique. The result is that you can record a hotter signal to the tape, without distortion, than you otherwise can.
      Cassette decks generally feature noise reduction, usually Dolby B and Dolby C. This is a process that modifies the signal before it gets to the tape, and there's a complementary process during playback that undoes the changes made during recording. The result is that the hiss, a high-pitched noise inherent in the tape itself, is pushed out of audible range.
      Dolby B recordings are more common (the deck in my car can only decode Dolby B), and due to how the process manipulates high frequencies, some people like to listen to a B recording with the decoding process disabled. It makes it sound brighter. Dolby C recordings feature better noise reduction, up to 20 dB instead of the 10 dB provided by Dolby B, but you do not want to listen to a Dolby C recording without the Dolby C mode enabled, nor do you want to play it in Dolby B mode.
      When you make a tape, you are recording a specific musical performance, a particular reality, as measured and imprinted by a unique combination of tape medium, capabilities, adjustments, settings and tunings, each of which you select. It is an individual act, resulting from a series of judgments you have made. You decide what music to record, onto which tape, using which device, and apply your knowledge, hearing and expertise, to create a real, physical thing, which only exists because you made it. What will you want to listen to next, the next time you play this cassette? What will you put on side one, what goes on side two? If it doesn't fit, and it never does, which songs get included, and which skipped?
      I've spent New Years making some cassette recordings. They are on TDK SA-90, which is not the type II tape which I used to align the cassette deck. So I've tuned the fine bias control. I also took some time to set the recording level. The NAD 6300 is a three-head deck, which means as the tape goes by, one head erases, one records, and one plays back. This, along with the input monitor switch, lets you hear both what you're recording, and the actual playback from the tape, as you're doing the recording. However, playback can be a different volume than the source, and louder things sound better, so you still have to adjust the playback volume when switching back and forth to hear the differences properly.
      These recordings are being made without noise reduction, because I discovered I could hear the difference in the brushed snares of a symphony orchestra going full blast, which is simultaneously a very loud sound, and a very subtle one. The detail was lost using Dolby C. That source was a Super Audio CD of the RCA Living Stereo 1959 and 1961 recording of Arthur Fiedler's Boston Pops Orchestra performing George Gershwin's Rhapsody in Blue. My goal is to record this performance, best I can, as if I were there, and recording the very event so I can listen to it later, as if I were there, crystallizing this experience into a single, physical, thing: the cassette.
      A cassette is more than just the tape, that thing you put into the deck, which is a precision-made shell that contains the actual plastic tape, several spinning hubs, a tiny spring-loaded pressure pad, and slip sheets to minimize friction. Cassette tapes also come with a plastic case, which holds both the cassette and the J card. The J card identifies the tape and describes its contents.
      In prerecorded tapes, it's a designed object, created with attention to colors, proportions, and appearance, just like the music itself, but generally by a graphic designer, rather than the musician. It's another representation of what is on the tape, in a different medium, print rather than sound.
      It should tell you what's on the tape, so you can tell it apart from the other tapes. It should also tell you the settings for the tape, whether you play it back with noise reduction, and what type of tape equalization to use.
      The J card can also contain production notes about the recording, such as the level the tape was recorded at, and any adjustments made to the fine bias. These can be useful for making better recordings next time.
      The J card should tell you what's important to know about the tape. And it should be beautiful, in its own way, like the music. Like all graphic design, it should be pleasing to look at, and convey specific information. For these New Years recordings I chose to use photographs of the deck itself, in the act of recording, showing the positions of the knobs, printed on 4x6 glossy photographic paper, carefully trimmed and folded. I love the way these tapes sound, and I love the way they look.
      In a very real sense, they literally are New Years Day, 2023. This is just like blogging, except when you're done, you've created a physical object, a cassette tape, a thing that exists, a captured musical event, a work of art.
December 2022
  December 29
    Why Twitter 3.0 is going to be the greatest
      (9 min read)
      We have finally figured out how to build and run a social network that maximizes freedom, safety and also profitability. We are building Twitter 3.0, on a handful of tested principles, to be the final social network.
      First, tie every account to a person. No fake people, this is important because fake people are really the worst. Bots are fine, because they belong to someone real and set a flag saying so.
      Fake people are just garbage data, trying to infect humanity with something terrible, which is generally stupidity so we will all fall easier for someone or other's scheme. So no fake people.
      You can make up whatever name you like, of course. You can have sock puppets for your various moods, but they’re aliases tied to the same main account. This allows for legit bots, pseudonymity, role-playing, masking for safety, avoiding being dead-named, and all the other perfectly reasonable reasons people have for not wanting to use their full legal name just to have an opinion, or create things and share things.
      Then you list the bad words you can’t say. This is a pretty short list, like just a few thousand things. The key is, the list needs to be comprehensive and vague so it can apply where it’s needed. I am kidding of course, that is how you build something that exists only to deny responsibility and just get through the end of another day.
      What you really do is have a sensible set of guidelines, like no fake people, and apply them where they're needed.
      But how do you know where it’s needed? This is the huge thing, right here. This is what makes or breaks your social network. And we've finally figured it out.
      There is one key lesson you can take away from every single successful site that deals with making user content available to other users. This is a lesson learned at interest-specific forums, Reddit, Metafilter, and many other online communities. You have to use humans.
      At scales such as Facebook, it is done with subcontractors in cheap places. Smaller communities, such as Reddit, are watched over by volunteers within the community. But you have to use humans.
      I can’t stress this enough, algorithms are only going to get you so far. There is no substitute. Humans are very good at figuring out how to navigate around the edges of algorithms. We use puns and misspellings and cultural references, and we mutate it all faster than software can adapt.
      In Twitter 3.0, automatic anti-fake measures, combined with a properly implemented flagging system, along with straightforward, easily applied moderator tools, ensure an approach that has a well-documented history of working well in practice, to ensure quality discussion with minimum drama. All at scales that might surprise you.
      Now, what differentiates a small community such as Reddit, or Metafilter, from a real social network like Twitter, is that there is only one conversation at a time. Everybody is participating in the same thread, so there’s a consensus reality going on.
      You can count on people flagging things that are outside the norm of a given space, ie, this-person-is-out-of-line, is something that is outside whatever norms usually hold for a particular space. Even in a social network you have myriad simultaneous conversations, you don't need a huge number of types of reasons for flagging. The number of reasons should match the number of rules you have.
      Flagging just denotes, I saw this and think this should be looked at by someone. It works no matter what kind of community you have. What it doesn’t handle is the little toxic cesspools of conversation, where everyone is in on the shitty behavior and they love it because they are getting away with it. The problem is, the little cesspools are private—and they should be.
      But we all have an interest in maintaining the safety and freedom of this new social network. So you handle this in two ways.
      First, you give people who aren’t members of the group the ability to flag content posted in private groups. This can involve a slight piercing of the veil of privacy, in that the content of the messages may be occasionally displayed to other safety-minded volunteers on the network. But the identity of the problematic participants can be obscured until really necessary, and after discussion with actual humans about when this is really necessary. And of course to ensure protection against retaliation, flagging naturally remains completely anonymous, as do appeal and final review.
      The other way you handle these private conversations is that you provide people an incentive to flag content in their own private conversations they otherwise might not. You grant privileges, or even daily cash back, and people will really want to step up and do the right thing.
      I don't have to tell you, of course this can absolutely be tied to what we are calling an "ethical NFT", which will absolutely be exchangeable for something of value at some point in the future for a completely plausible reason. You can trust this plan, because it comes from a real billionaire. Not one of those imaginary-money bilionaires.
      We all love codenames for things, it helps you focus when you're building it, and it helps focus people's attention, it's like a mini brand name. Because this structure is specifically designed to maximize freedom, participation, safety and stability, we've come up with what I think is a fantastic name for this part of the project. So incredibly excited. I really like the way it rolls off the tongue. Very snazzy.
      The key is stability, security, safety. Think stability, think status quo, think rock solid, think conservative, think stasis—
      Stasi. It’s for you!
      Now, this next part is critical to our goal of bringing social networking into the next era, beyond what's already been possible. We are going to amplify the possible, we are going to lift the possible to another level. We are going to unite the online with the offline.
      We are going to maximize independence and freedom right into the real world. This amazing country was built on the power of the individual, working alone, standing astride history with hammer held high, declaring, “Here we shall build our homes and our liberty.”
      Twitter 3.0 is going to be true to that spirit in ways no one has ever seen.
      To maximize freedom and independence, we maximize the freedom and independence of the individual. Remember, our members are real people, with as many names as the want, readily available to preserve anonymity and maximize communication. People adopt personas for many reasons, and one of those reasons is to tell the truth to power.
      You’ll be able to participate in a way that ensures that no one will ever know it was you. You’ll be able to communicate in real time with similarly-minded, freedom-loving individuals, and you won’t even need to know their real name.
      I’ve already described how moderation works, so this anonymous network is also guaranteed to be completely safe. We use end-to-end cryptography and conversations are permanently available to everyone involved, so everyone can keep in touch and know what’s been going on. (Don’t worry, if it turns out later you need to, with one click the entire thing can go away, permanently, because we don’t keep any backups.)
      Twitter 3.0 has also got some really great features for families, that help keep us safe, and find new things. We call this part "Theme Park Mode".
      Theme Park Mode lets you share a detailed, 3-dimensional topographical map overlaid in real time with the exact location of every member of your family. Augmented reality features let you scan the horizon and immediately see visual markers telling you where your family members are—just like a quest in a video game.
      Need to tell the twins to head to the roller coaster, while Dad needs to pick up some snacks and then meet somewhere else, all at the same time? It’s super easy to split out little groups like this and still keep everyone in sync.
      Real time push-to-talk; live task assignment, update and completion (“make it chocolate!”); instant note-sharing; inventory tracking (“who has the baby wipes?”). And voice-activated mode for smart assistant earbuds, for the inevitable times when your hands are full. Active noise cancellation lets you hear your family even in the middle of crowds.
      Naturally, Theme Park Mode works with all kinds of groups, not just families. It’s going to be fantastic for church groups and school field trips. It's going to be fanatastic for tourists, and experiential artists, or even just heading down to the mall with a few close friends.
      This is another lesson we're adopting from smaller, interest-bound communities. It turns out people like to meet up, even if they’ve never met. Getting together in real life, to talk about things you care passionately about, even if you’ve never met, and may never meet again? Well, that’s a special human connection that we’re proud to help enable. No matter where it takes us all.
      Along with Theme Park Mode, we’ve got big plans for a little thing that we’re calling Quest Mode. We are going to empower anybody to build an augmented reality game. You’ll be able to build your own treasure hunts, and pretend spy thrillers, secret monster hunters, you name it.
      We've got full, high-resolution, 3-D maps of every street, every sidewalk, every park, and every building in major cities around the world. We’re launching with a salute to every state capitol, and major metropolitan center, which means you’ll be able to lay out your puzzles and goals using real buildings, real doors, real windows.
      And because anybody can make one of these games, and anybody can participate, practically anything can happen! You can even update your game in real time, change things up to keep your players on their toes.
      And our patented algorithms will help your players, your families, your friends, your neighbors, even thousands of people you’ve never met and will never meet again, all come together to participate in something amazing. Maybe even world-changing, history-making! Wouldn't that be something.
      Of course, we haven't forgotten our commitment to safety. And here's where we have a unique opportunity all of human history: Tesla.
      Self-driving capable cars like Teslas are just bristling with sensors, and you don’t need to be sitting in one to make use of it. People are going to love how safe this makes everything.
      Even when your kid’s cell has run out of battery, you’ll be able to locate them anywhere. Even if they’ve gone behind closed doors, you’ll know just where those doors are.
      Because at some point, on the way there, they walked past a Tesla. Or a Tesla drove by, looking really cool, like a Tesla. And that Tesla noticed. And told Twitter. Possibly also SpaceX.
      (It definitely told the AI that remembers everything that ever happens to everybody, and looks for patterns to be exploited, in service to Its Holy Owner, which I just totally made up, and isn't a real thing a truly godlike billionaire would order built.)
      Twitter 3.0 will make it so easy to send someone trusted to pick your kids up, or whoever you're looking for, and escort them right where they really belong. It's like knowing everybody around you, personally, and always being able to call on people you trust.
      And because humans look out for each other, it’ll be easy to tag houses in your neighborhood so everyone can see where to get the good candy on Halloween, or who needs an extra little watching after. Never know who might need looking after. You can keep a list, subscribe to lists of people you trust. People you can count on. Count on to be there, and step up, and do what needs to be done. To whomever it needs doing.
      The essence of this project, the emphasis is on mobile. Think mobility. Flexibility, maneuverability. Being at the right place at the right time—hundreds of places, all simultaneously. Staying in connection with everyone and everything around you, yet still able to focus, and move, stay in motion, stay mobile. Motion. Mobile—
      Mob. Join it!
      Twitter 3.0 is going to be everything you love about America, turned up to 15. Plus crypto, don't forget that.
  December 28
    Why again is Mastadon not just DNS and RSS?
      (1 min read)
      I am wondering why I should have to do anything like set up an account on a Mastodon server to be able to say, "follow me on Mastodon at my-name@my-server.com" if the blog part has an RSS feed.
      There should be a DNS entry I can maintain that could point my-name@my-server.com to an RSS feed, or some other simple, plain file format that contains a list of recent status updates. I think that takes care of everything you need to follow someone, an easy way to get to a known place for a list of updates for an identity.
      The rest is federation, which is moderation, synchronization and caching, which is all definitely useful. But not literally necessary to the task of saying "hello, here are the latest posts associated with my-name@my-server.com".
      I guess this post is part, "why are we redoing it again", again, and part, "why should I have to do anything other than have an RSS feed to be a participant in the larger conversation", and part, "look at the virtuality friction".
    Virtuality friction
      (3 min read)
      Some days, you spend most of it waiting for the test to fail. Finally, at the right spot, for the right reason. Now you know why it's broken, and now you can fix it.
      If you are also writing the test infrastructure around that code, the code that tests the code, then it is harder to be sure about where the problem is. This is why I like test equipment. You can guarantee it will perform to spec, and as long as you maintain it, it will always perform to spec. If it doesn't, it's out of spec! It's beautiful, really, how it all works out.
      Automated testing is a new thing in software development, by which I mean, it is something from the most recent 20 years of computing, rather than the first 20 years of computing.
      There was a period in between where things changed pretty slowly, because performance just wasn't good enough, no matter how fast the hardware changed, you still had to rewrite your software to take advantage of it. You can think of this as friction between the performance of the intended virtuality and its ability to be expressed in hardware and software. This friction is the amount of time you spend optimizing for the particular platform, the cost of implementing in your code a feature that in later generations would be provided by the system.
      Longer word lengths, and more registers, and access to large amounts of memory, and device access, and file structure, network access, graphics generation, fonts, animation, state machines, garbage handling, request handling, response generation, pipes, handles, sockets, key-value storage, structured data storage, multiple-host synchronization. Each layer reduces this virtuality friction. Each layer enables other layers.
      If you need a layer, and it is not yet part of what you can count on, you are building it yourself. That is the friction. At one point, you needed to manage the contents of registers yourself. Later, you'd write your own random number routine because your game needed that.
      Automated testing is the layer that allows you to know for a fact that you haven't broken anything. You can't fool the compiler. And you can't fool the test. If something breaks, you add a new test, and then fix the broken thing. Passing the test means you fixed the bug, and since it's a test, you can run it again, automatically, and know for a fact that you didn't break it. Anytime you rely on manually verifying something worked, instead of having a robot do it for you, eventually you will forget to keep verifying it, because we expect things to never break, so why keep checking? But eventually it will have broken when you weren't checking.
      Now, you can create applications that are websites that are social connections that are protocols that are just literally when you get down to it, just a couple key things, a handful of short strings defining what kind of information to look for, in what place, and how to build these strings. For example, RSS or json.
      The actual mathematical structure defined by these standards is extremely simple, and the entire rest of technology is built around generating and manipulating these things in all the ways we can think of. This is where we are currently paying most of the costs of virtuality friction.
      As it becomes easier to treat working with these strings as fundamental capabilities, ignoring things like in-memory, on local disk, local network cache, same-host service, local network service, caching proxy to load-balanced cluster, remote server, pooled connection, database index structure, query structure, query optimizations, cache optimizations, and strategies of all sort, we can finally build other things on top of all that. That of course becomes the new level of virtuality friction.
    Why are there billionaires
      (1 min read)
      I think this is how billionaires have always happened: They are in between the gears, like grease, making things a little smoother, but mostly extracting wealth from the changes the rest of society would have done anyway.
      They always believe they are great men, who deserve to be where they are because of who they are. But they are not.
      Someone as great as they believe themselves, as great as their reality has assured them they actually are, surrounded by nobody who could do anything but validate every fleeting whimsy as sheer genius wisdom, fulfill every request without considering costs, listen, and excel in one key ability: knowing exactly what to say to the billionaire, to stay close to the billionaires, someone as great as all that would have found a way to contribute to society without needing to grow ever richer, forever, always gaining power, always needing more, dreaming of breaking down society itself, to reshape it for their own use, to piss on contracts and promises, and laws and regulations and fines and criticism.
      But they never do, they are always greedy, and whiny, and need more, always more, and cannot stand anybody who says no, or even hesitates. It is literally how they are built as human beings, and that type of human being naturally ends up where they are, controlling the resources they do, because we let them, because it is literally how we are built as human beings. The rich will always be among us.
      (What actually would happen if we nationalized all the billionaires?)
  December 27
    Just realized how to add buttons to the blog part that say "MORE ANGRY", "LESS ANGRY" and have AI-generated text where the prompt consists of the original post, except angrier, or stupider, or rhyming, etc., iterated as desired. Like a knob you can turn up or down, a filter, applied to the text.
    Fixing it
      (2 min read)
      "I can't mess with anything or else it will break." Welcome to my world, kid. Everything wants to break, all the time. Sometimes you can fix it. You never know.
      Tonight we listened to music played by my other new tape deck from 1986, the NAD 6240 Stereo Cassette Deck. This lasted for as long as the kid could stand, which was not as long as I'd have liked, but longer than I think would actually cause him to drop dead from not being able to put the Nintendo Switch on the big screen. So not too long. But long enough for me to feel pretty good, because I fixed it myself.
      The first tape deck I ever purchased was an NAD 6240. I am pretty sure I got it on discount because it was the previous year's model, but I selected carefully. It was the best cassette deck I could afford. I really wanted an NAD 6300, but they were several months' rent. Later I traded that deck to a friend for an NAD 6325, which I never liked as much (the deck, not the friend). I looked up the specs recently, and it turns out that deck rolls off at 15 kHz because there's no MPX filter switch. So apparently I could hear that difference.
      I don't trust my ears too much, because it turns out my ears are kind of slutty. They like the sound of everything. I get used to the sound of something, and I can find something to grab onto and marvel at, no matter how high fidelity or digital or pure it isn't. You can get everything you need from music from a mono AM radio. Music is magic that way.
      I fixed the playback on the NAD 6240 thanks to a thread on Tapeheads. The output was down around 6 dB in the right channel, and even more on the left. I replaced a capacitor that had gone dead, and now playback works great. Recording is another matter, it is completely broken in that way, so I have more to do. But tonight we listened to a TDK AD60, recorded on the NAD 6300, of Melos, Vassilis Tsabropoulos, Anja Lechner, U.T. Gandhi. Lots of piano and violins. I haven't done any mechanical work such as changing the belts, or lubrication, on the 6240 yet. Its wow and flutter are already basically within spec, 0.08%, so I could leave that alone if I wanted. (I will not be leaving it alone, of course.)
      This is the other system, which is a pair of Alexis Sound monitors, which feature crossovers by Dennis Murphy, driven by a TU-8500 tube preamp I built from an Elekit, with power and gain provided by a Blue Circle Audio BC204 hybrid power amp. I call this the mono rig because the record player hooked up is outfitted with a mono cartridge, but it's stereo. And it sounded really, really good. The TDK AD is a Type I cassette, not the fancy chrome, and the 6300 that made the recording was calibrated to Maxell UD XLI, and I haven't done any adjusting to the bias, nor really tried to optimize recording levels yet.
      But it sounded really, really good. And I fixed it myself.
  December 26
    Boxing day
      (6 min read)
      I am finally sitting down in the good chair, between the big speakers. It's been a few weeks of learning about cassette decks and how to set them up properly, and then doing it, over and over, until I get it right. I'm listening to a recording of Norah Jones from a Maxell XL II tape recorded from a Super Audio CD directly from the Oppo BDP83-SE to the NAD 6300 I've finally declared ready to listen to.
      The speakers are being driven by a pair of Class A amplifiers based on the Nelson Pass F-4, which I built myself several years ago, and refer to as the Wild Side and the Weasel Side. Class A means they sound great until they get hot to the touch, at which point they sound amazing. They're my winter amps. They don't provide any gain, just current, lots and lots of current, so I have the Parasound P/LD-1100 Line Drive to swing the volts required to make the big speakers sing. They are six feet tall and just two inches thick, like great golden monoliths, and they are Magnepans, and listening to them is like wearing headphones that are six feet tall.
      The audio on the Super Audio CD is recorded in DSD, which is not like ordinary PCM audio at all. You can get the digital output in PCM form, it's 88.2 KHz and sounds great, but it's not what's on the disk. DSD audio runs at a clock rate in the megahertz, and it doesn't sample the voltage, and convert it to a binary number corresponding to the scaled value, which is what you normally think of when you think of how a DAC works. DSD just records stream of ups and downs. Is the voltage rising, or falling? There's your ones and zeroes. You don't need 16-bit words. What you do need, is a special player. You cannot listen to a Super Audio CD on a regular CD player. There may be a regular Red Book audio layer for your regular CD player, but you will not be listening to the DSD version.
      You also can't rip a Super Audio CD to a digital file. You can intercept the digital audio going through the HDMI output, and get that 88.2K stream, but you cannot get the DSD bits. That's because we're all dirty filthy pirates, of course. We brought it on ourselves.
      So the only way to listen to these discs is on the Oppo, which they stopped making because making great DVD and Blu-Ray players was distracting from cellphones. And since the only thing you get as output from a Super Audio CD is actually analog audio, why not record that to a cassette tape, and then listen to the tape instead? This sounds insane. The entire point of digital audio is absolute fidelity to the original source. No distortion.
      But actually, we like distortion. Nelson Pass has noted that about half his customers preferred a little second harmonic, and the other half preferred a little third harmonic. And because he is a genius at this, he can tune his amps to produce extremely pleasing flavors of distortion. The F4's are mainly second harmonic, which is generally considered warmer, versus the more crisp sound you'll get with the third-harmonic variants. They don't have much distortion anyway, and running them as mono blocks cuts that by another 3 dB.
      Audiophiles, at least those of a certain nervous sort, focus on short signal paths, purity and low distortion. Even tone controls, your regular treble and bass knobs, are considered bad, because they change the sound, on purpose. The fewer changes, the better. This is what is referred to as the "absolute sound", which is precisely how the music literally is, which is a real thing that you can totally reproduce, or get at least keep as a shining beacon on the horizon, as you perpetually upgrade your gear, and settle down for some critical listening. Discrete circuitry, no chips, no op-amps even. The less, the better. (This basically describes the F4's actually. They are nothing but a handful of transistors, the power supply, and lots of heat sinks.)
      The thing that cracks me up, though, is just how mangled the sound was on the way to that recording. There are so many op amps in pro audio. Everything's been filtered, and boosted, and cut, and panned, and impedance matched, and run through so many transformers and coupling capacitors, and resampled, and reclocked. And that's before you even get to the mastering part, where everything gets another sheen of tiny boosts and cuts and feather touches of compression, and finally it sounds like natural, pure music.
      Using a cassette deck can be considered a way of adding distortion to a recording. In fact, several of the steps in the recording studio rely on the specific distortion added by tape recording, so there are digital plug-ins that apply this distortion right in the DAW, lots of them. (And, I haven't looked, but they probably all model the same handful of classic tape machines. There is magic in using the exact same equipment used to make famous recordings. Maybe the luck will rub off.)
      When I get new equipment, which usually is actually old equipment, from eBay, I like to fix it up so it matches the factory specs. Test equipment generally has great documentation, with step-by-step instructions for getting it back into spec. Follow the steps, and it will perform as it should. This, for me, is one of the fun parts.
      The NAD 6300 has hundreds of little fiddly parts, and dozens of fiddly steps, to get it working properly. I am still trying on the wow and flutter. Wow is slow changes in tape speed, generally below 6 Hz, flutter is the faster stuff, generally up to around 200 Hz. It's basically the analog version of jitter. You can really hear it with piano, if it's bad. This deck should be able to do 0.025% weighted JIS, which is really quite good, and it's at 0.05% right now, which is really only excellent. So there's still room for improvement there.
      But the electronics are on the dot, they have been dialed in, and dialed in, and gone over, the entire 25-step process, repeated several times from scratch. The entire purpose of this device, now, is to add distortion, but as carefully and precisely applied as possible. So some steps you just do over and over, seeing if you can get a difference down to 0.01 dB, even though it was in spec back when it was 2.5 dB, ten minutes ago.
      And while I already had the HP 8903A distortion analyzer, and the Meguro MK-668D wow flutter meter, and the Keithley 2015 THD multimeter, and a bunch of other really quite neat, and not boring at all, test equipment, I did not have an Information Terminals M-300 alignment gauge, nor did I have a bunch of test tapes with various precise signals recorded with precision, nor a torque meter cassette, so it was fun getting that stuff, and learning how to use it, too.
      It's been several weeks of evenings and weekends, and now I'm finally sitting in the good chair, listening to Thelonius Monk, and his gorgeous piano. It sounds pretty good. I did good. I am happy.
  December 17
    Nearly every one of the several hundred parts that go into a cassette deck is tiny, and will go flying with a little "ting" sound if you grip it too tightly with the pliers. If you're lucky, you'll find it in the carpet after an hour of searching. If not, you keep looking. I hate little fiddly things, always have. I am not mechanically minded. I break pretty much everything, often while simply removing purchases from the packaging. I've lost this little clip a half dozen times now. But I have decided that I am going to do this. I am tired of not completing projects just because they are hard. Everything is hard.
  December 16
    Recent bans of journalists and non-Nazis demonstrate that if you annoy Elon, you can lose your Twitter account. I need my Twitter account because Drummer uses it for login. If I lose my Twitter account, I won't be able to update the blog part. Fuck you, Elon. You fucking asshole.
  December 9
    Apparently FeedLand's "my feed" isn't actually my feed, and is intended just for making comments about FeedLand. So I guess I will have to come up with some other way to make quick posts to the blog part from my phone. Disappointed.
    As a proud union member who does not cross picket lines, turning off the New York Times feeds at the root level of FeedLand feels like the Musk approach. Unsubscribing from them on your own feed seems better to me. If there’s a social aspect to using FeedLand, it is users following each other’s curation judgments. Not the owner of the platform using the platform itself to express personal judgments.
  December 7
    Driving the kiddo to school this morning and forgot to bring any tapes to listen to, so I had the radio on. “What’s that sound?” he asks. “Is it on purpose?” He has never heard static before…
  December 6
    Brief updates from pmg
      Experimenting with FeedLand's "my feed" feature. Added an RSS node to a scratchpad tab in Drummer, expanding it refreshes the posts from my feed. Copy-pasted the nodes here, let's see how they look:
      Just got a brand new NAD 6300 tape deck from 1986. Listening to a prerecorded Guardians of the Galaxy Awesome Mix. Holy moly this thing sounds amazing.
      Listening through the craziest chain. NAD 6300 cassette deck into TAC-8 Thunderbolt audio interface, using Logic Pro input monitoring, run through a Waves plugin which reproduces in binaural audio the acoustics of the actual Abbey Road studio mixing room, via Denon D7200 headphones. It’s analog, it’s digital. Have spent no time tuning, calibrating or aligning. Sounds amazing.
      Now to figure out the easiest way to get these posts into my Drummer blog.
      Looks like the easiest way to get the posts from my FeedLand feed into Drummer is to just subscribe to my feed in Drummer by creating an RSS node, double-clicking it, and then copy-pasting the refreshed posts into my blog. Not so bad. Getting closer to my ideal scenario of being able to update my Drummer blog with quick thoughts from the phone.
November 2022
  November 27
    Superhero series that probably exist
      Uncle Ben is actually a womanizing cat burglar and con man with a gambling problem. He's kindly to his family and friends, unless he's been drinking.
      Batman is a vampire. His car has really cool red accent lighting. He fights crime but he also must feed.
      Superman does manual labor, for pay.
      Peter fights crime because he must atone for the things Uncle Ben made him do. And the things he makes him do now. That voice.
      Aunt May is full of spiders.
  November 26
    Upgrading my system to maximum hassle, with a cassette deck
      (4 min read)
      Because I like test equipment, and I like audio equipment, and I like fiddling around with knobs and dials, and I like music, and I like learning new things, and I like the things I liked when I was younger, I have bought a cassette deck from 1986.
      It is cold and dark, so we take the Jetta wagon to school instead of the fun car. This car has a CD player, but it also has a cassette player. We've been listening to the Traveling Wilburys and the Awesome Mix tapes from Guardians of the Galaxy. This has been fun, and part of the fun has been showing off all the little things about how it used to be in the olden times.
      There is no song navigation, which means you can't pick a song from a list. You can't skip to the next song, either. What you get instead is called "fast forward", which is not fast, and "reverse", which is also not fast: it can take like ten or fifteen seconds to skip a song. You can never be sure exactly how long this will take, so you need to stop and play every few seconds.
      Also it always picks up from where you left off. Like, if it's in the middle of a song when you parked the car, it will be on that song when you get back. Unless you hit the eject button, then it might be in the middle of some other song, because that song is on the "other side" of the tape. The songs on the other side are in backward order. If you fast forward on this side, it goes backward in time on the other side. It's a mirror universe over there, where time flows exactly opposite to ours. This is not how time travel and parallel universes generally work in movies, so it can take some getting used to.
      You get like four or five tapes in the car, or as many as you like in a pile on the floor, because these things are huge and only contain a couple dozen songs each.
      If you eject the tape, you have to put it back into a little plastic case, which provides no real protection, and which itself is easily damaged. It's also super fiddly, and not in good way. You do this because the case's job isn't to protect the cassette, which is actually pretty hardy if you disregard the whole "spools of flimsy, stretchy plastic" thing. The case is there to store the J card, which has all the navigation info and documentation for this release, printed in extremely small type, in white knocked out of poorly registered four-color black, which means it's fuzzy and has color halos.
      Together, all these limitations of this technology, combine to produce a default scenario where you listen to one side of the tape all the way through, flip the tape to the other side, and then listen to the other side, in a loop. In the real world, you will end up liking one side more than another, or just one song on one side, so you learn to navigate the whole parallel-universe-backwards-time thing. It's fun!
      I only have three tapes anyway, because at some point I got rid of all my tapes, of which I had a few hundred. I got rid of them because that is a lot of tapes.
      Before I got rid of the tapes, and the tape deck, I transferred some to mp3. Except of course the dozens I didn't transfer because I got bored with the project. You have to import the songs in real time, there is no fast forward, if an album is 45 minutes long then it takes 45 minutes to transfer. You have to adjust the volume manually. You want the loudest possible signal for best results, but tapes are produced at all sorts of levels, so you have to watch the meters.
      But now I have no tapes. To get tapes, I can either buy new tapes, or make my own tapes. When you make your own tapes, you can pick your own songs, and put them the order you like. This is the mix tape.
      Making a mix tape takes a lot of time, because you have to get all the records out, and find the song, and get the record out of the jacket, and flip it over, and put the needle down, and press Record, and listen to the entire song, and press Pause. Then do it over again for the next song.
      (Also, the Record button is often actually two buttons, which you hold down like you're playing a chord on a piano. It's a skill. You gain a lot of skills with cassette technology, is what I am saying.)
      This is going to be loads of fun.
  November 9
    My new superpower is knowing what to do next.
  November 8
    I don’t follow anyone on Twitter, I’ve just been using it for the past 12 years as a place to type quick thoughts to get them out of my head. So the new Edit my feed command in FeedLand ought to be perfect for me. But, like Drummer, FeedLand is way too hard to use on the phone.
  November 6
    Now witness the power of this partially operational chaos factory. All the lab equipment is finally back online. Made maybe a hundred or so connections today, and sorted a dozen cubic feet of wires, plugs, adaptors, tools, screws, risers, widgets, cables, power supplies, test leads and various other things. Finally found that carriage bolt. Need more bins.
    Never underestimate the importance of a well-organized workspace.
  November 5
    I have cut my first record! It sounds so, so incredibly terrible. I love it.
    I managed to acquire a PO-80 Record Factory during the brief time it was available at the teenage engineering website at the offering price, $159 plus accessories like additional blank vinyl records, cutting needles, and the carry case. There are a couple on eBay right now for around $600. If I had any sense at all, I'd just sell it for a nice profit. Of course, instead I am going to put it together.
    Feedle is a new search engine for blogs and podcasts, apparently powered by RSS. You can get an RSS feed for your search results. It looks interesting, but I can't find the RSS feed for their top stories page, and it really seems like there should be one.
    I have been stupidly, ridiculously busy lately, putting together all the things so I can make all the things. These next three pieces need work, but it's better if I just post the drafts now and move on, rather than sit on them until they're done.
    You feel exactly the way I do right now
      (1 min read)
      There's a beat that goes with this, it's stumbly. Bump baddaaddabumpbump bump dash uh uh uh.
      You feel exactly the way that you do right now. It's not a science experiment, though it could be. There's a beat that goes with this.
      You don't have to go out and find a beat, and make sense of what you're feeling right now. That's you. That's right.
      So you don't need to do whatever it is that you do, however it is that you do, just go on doing that with your bad self. But you can make your own new beat if you like. And this experience that you are doing, well, that right there? That there is magic. It's you.
      Whatever beat you want that goes with this, that is what this beat is. You feel exactly the way I do right now. And that is you right there. You.
      There's a beat that goes with this. I just have to go hook up the mic.
      It's stumbly. But you make your own beat, you do what you like.
      This is the art part.
      If it takes more time, that's how much time it takes. You get to spend a little more time doing that right there. Hopefully there's a beat that goes with it.
      It does not have to be a dope song, with a hypnotic beat, going round and around and around in your head. It can just be a blog post, like this one.
      But you take this idea, this part, this part, the art part, right here, and express it yourself, wherever you are, doing whatever it is that you are doing, you express that. You make your own art. And that idea that is coming through to you right now, because of the art that you are receiving, however this is being expressed to you, in such a way, that you can experiencing right now, that is the art part. And you make it yourself. And you record it, however it is that you record what it is to be you, you record that. That experience that you are going through, that's the art part. And we all make it ourselves.
      There's a beat that goes with this. You'll hear it. Just listen.
    What is this blog post about?
      (2 min read)
      This blog post exists as one specific embodiment of the larger art work that it describes. It is not the entire thing, it cannot be. It is just the blog part. The larger art work exists in a conceptual space, the hypothetical space, options. It is that space.
      Reality is clumpy, it is held together and made of fractals and power laws. Making large changes requires large amounts of change. The speed of light is the speed of reality. You squish it hard in one direction, it becomes a hologram, a single change, one commit to reality, like git. The largest lumps are called kurts. This is reality, where you are, right now, all the rules and state that make up now, the present, but with all the weight of history behind it, and what comes after, up ahead.
      Everything is always happening, right now, everywhere at once. Making large changes require you to know what has come before, and that transformation, that difference between just now, and what came before, that is called the cobain. It is the difference between where you are and what you are, and what everything there is around you is, and what it is going to be once this moment has passed. The cobain is a mathematically applied manipulation to reality, the exact definition of that which needs to be different, to get from here, where we are, wherever that happens to be at the moment, to there, wherever we are going to be.
      Reality is clumpy, but it changes. Larger clumps of reality, what you'd call a parallel universe, movie-style, exist as perturbations of the cobain, clumped together, as a power law, as a fractal, and propagate at the speed of light. There's THINGs, which exist, movie-style, as gods, because what they are is defined literally between kurts, between the cobain itself. Also they make good storytelling.
      But that description of reality, with kurts and cobains, and THINGs, and whatnot, that is not what this particular blog post is about. That's one way of viewing, experiencing, creating what we are right now. It is one embodiment of what this particular blog post is about.
      This is the art part. The art part is the part where you are doing what you are doing, right now. Just like me. I'm saying it again because I like repetition, because repetition is time, it is change, it is frequency, it is happening everywhere and it is clumping. In mine, there's a beat that goes with this. It's easier to hear if you say it out loud. That's the art part. It keeps happening, we all make it all the time.
      The art part is where we say it out loud.
      That's what this post is, what the blog part is. It is one part of the art, one specific embodiment of a description of the way the universe is, and how to view it, and how to change it, how to explain it, how to make it happen, how to make it all happen.
    That terrible thing we are all careening toward
      (2 min read)
      How you experience reality defines who you are, and that can be changed. We go with what's around us.
      If everybody else in the room is saying insane things, we listen to what they're saying, and we agree, because that's how reality is. That's how it works. Your expectations are what has happened to you. One day, there are two sides, and the next, there is just one side, because that's just what happened, and everyone will probably get over it, because there are things to do.
      I am not kidding about this, humans are capable of scary things.
      And we live in a place where many, many people have all the weapons they need, more weapons than they need, weapons they couldn't possibly use in a lifetime of peaceful murder and mayhem, all waiting there, just waiting to be used and loved for their glorious murderous joyous what-had-to-happen-but-it's-all-better-now, more weapons than even that, quite frankly, I'm talking about just a stupendous number of high-powered ways to murder as many people as quickly as possible, then multiply that by a very, very large number, that kind of mind-boggling amount of firepower just itching to be used, let's say it's a wonder there aren't mass murders and political killings and showing people who's boss once and for all, happening each and every day, all the time, everywhere.
      Some are just waiting for their turn, for permission. Permission to go nuts. Permission to finally use all those sweet, wonderful weapons, and put an end to everyone who is different. Twitter has been instrumental in granting that permission.
      I mean, someone always has to pay. And everybody is going along with it, like it's some sort of fucking joke. Elon, you fucking asshole. I know what you're up to. We all know. All Elon cares about is Elon, just like Putin, just like Trump. Twitter wasn't a net good for society before you got hold of it, and something tells me you like that. I know what you can do to people with your money. Continue to fuck yourself with all the money and expertise and resources you have, because I know you like that, we all do, we all want what you want, the way you want it, all the time, in every possible way.
      The blog part is about works of art that talk about where the world is, and how it got there, and how it's going to be next. Twitter is a sideshow compared to what is coming. Twitter is just part of how we are getting there, how we got to this point, and how everything is just going to "just happen" and suddenly millions of people are dead. I don't think any one person can change that, it's like climate change. But some of us can make it far, far worse, some of us have the ability to really fuck shit up, and they are not used to being told no.
October 2022
  October 29
    I only noticed the FeedLand likes for all users feed today, and I like it. I subscribed to it in FeedLand, of course. But the individual items in the feed don't show where they came from in my river view. Part of my decision-making process for "should I read or trust this article" involves knowing the source. I suppose you could mouseover or something to see the article URL. But I do nearly all my reading on the phone.
    The FeedLand personalized news page I use now as part of my regular reading, i.e., all day long, stopped working with an error message about an inability to get something undefined. This was unexpected, but easy to fix in the FeedLand settings dialog. Put at least one category into the News product box.
  October 20
    Air quality index was at 293 when I went to bed, still at 260 ("very unhealthy") this morning. Starting to agree with Frankenstein on the whole FIRE BAD thing.
    I ended up unsubscribing from Hacker News on FeedLand because it updates all the time, and I think that was pushing items from less frequent sources off the end of my untabbed river page. (Not sure how many items, or how far back in time, the river goes, actually. That page has turned out to be the one I use most often, because I do most of my reading on my phone. I am probably not a typical reader for rivers of news. I should write a bit more about that at some point, because maybe there are more like me.
  October 10
    Apparently every FeedLand user has a news product page, or something like it. This is the one for my account. It doesn't have my tabs, and it's unlabeled, so I dunno if this is a bug or a feature.
    It would be neat if I could subscribe to a feed directly from a FeedLand news product page. Right now if you see something interesting in a river, I think you need to find that user's page and locate the feed in their list of subscriptions. The link to the XML viewer page for the feed is useful, I guess, but I keep expecting it to take me to somewhere in FeedLand so I can subscribe. Perhaps that might be considered an attempt at lock-in. But some sort of "add to FeedLand" or "view in FeedLand" icon would save a whole series of clicks and round-trips, and people are used to seeing little Twitter, Facebook, etc. icons already, so there's precedent.
  October 9
    It would be handy if I could categorize a feed at the same time that I subscribe to it from the hotlist page in FeedLand. The "choose categories for feed" icon shows up for feeds you've already subscribed to, so once you've clicked the checkbox, you need to refresh the page and scroll back down the list to get it to appear.
    I prefer the rendering of feed items in the mailbox view in FeedLand to the river view. The river view seems to omit line breaks for some feeds, and other formatting, that show up in the mailbox view.
    You can reorder your tabs in the river view by changing the order of categories in your settings in FeedLand, but I can't figure out how to tell it which tab to default to. Looks like it always defaults to the second category in your list, but that seems a bit weird.
    I've assigned my feeds to three categories in FeedLand. If I set one of them as my category for home page news, items from the other categories show up as well. Not sure if this is a bug or I am misunderstanding what that setting is for.
    Nice, new posts seem to be showing up instantly in FeedLand now. I think the feed may need to support rssCloud, but mine does, so maybe others do, too.
    FeedLand lets you create something called a "news product", a curated river of news built from a collection of feeds. Here's one Ken Smith has created for news from NASA. It seems like I ought to be able to subscribe to that news product via a checkbox. Perhaps there's an RSS feed for it that I can't find. It would also be neat to be able to see which feeds make up that river from within FeedLand, too.
    Some FeedLand news products, like this one, have an XML icon that looks like it should provide a list of the feeds that make up the river. But the OPML file appears to be empty. It looks like the linked URL puts the category where the name of the user that created it should go, and uses "undefined" as the category.
  October 8
    Tangle Tower disappeared from the Apple Arcade recently, but the game still worked if you'd already downloaded it. Until just now. Even if you have it on your computer or iPad, when you launch it, you get a dialog box telling you it's no longer available. Extremely disappointing, and I had no idea Apple could—or would—even do that. My kid LOVES this game, and it is (was) fantastic.
    I wish there was a button for "check feed now" somewhere in FeedLand, rather than having to find the URL and paste it into a dialog box.
    The date used for "when the feed last updated" apparently defaults to when the feed was added to FeedLand, rather than the date of the most recent entry found when the feed was added.
    The mailbox view in FeedLand will show you posts that haven't yet shown up in the river.
    I was surprised to find that assigning a feed to a category in FeedLand apparently puts it back into the subscription log as a newly-subscribed feed. Perhaps that's because I created categories but omitted the "all" category, and then later added it back because I couldn't figure out where all my as-yet-uncategorized feeds had gone.
  October 5
    Everything's different, and it's all the same. I haven't had much time for writing lately, though I've had nothing but time. Sometimes you need to take a step back and take care of things long neglected. I feel better when I get up and do things. This can be a hard lesson to learn, but I am learning it. And it's been good. Time to get to work. (Illustration by DALL-E)
  October 4
    I've just come back from one of the worst times in my life, one that's lasted for years. Nothing's changed besides me, and I'm still the same. Except this time, it's OK. (Illustration by DALL-E)
September 2022
  September 20
    Hope
      (5 min read)
      I am watching TV because this is the absolute best thing I could be doing, among all the choices, in all the possible nows, of all the ways everyone before me died so that I might be human.
      It's a heavy burden to bear, but I can do it. I am sure of this. Pretty sure.
      Each thing we do, each act of creation, each moment of every life, says, "it will get better." This meal will be delicious, and it will sate my hunger. This drink will take it all away, finally. This child, these thirty hours of screaming and blood, and the feel of the bones in your hand being crushed as she grips, telling her, promising it will all be worth it, and you will never ask her to go through this again, it will only be just this once, and just think how wonderful it will be when that little sparrow is finally here. It will be better, it will, it will, it will.
      This can't possibly be, of course. It can never always get better. Life isn't like that. If it did, why, that would be heaven, right? We all know the answer to that one, it's a trick question: that particular heaven would be hell. This is life, and you do what you can.
      So the hope we express in every single moment of every single fractional action, eternally frozen in the past, can only be dashed, again and again and again.
      We make movies and tell stories about those who no longer give a fuck about what hope says, what the rules say, what anybody thinks, they are going to change the world and they did. This is how we know who we are, the only way. Those stories are us.
      The wealthy and powerful are facts, like mountains and twigs. You cannot change these things. If you are wealthy and powerful, your children will be wealthy and powerful, and will tell others what to do, just like you, and those who came before you. Their days will be filled with leisure, and joy, and it will always, always be getting better. They'll watch a lot of TV.
      If you strive like they do in the stories, that could be you. This is how it's supposed to go. You can never, ever give up hope.
      When all is said and done, all you really have is friends and family. Some of us get statues, and some of those get torn down later by the living. The rest of us only get talked about by those who knew us. If you're an asshole, I'm sorry, I guess, but maybe people will talk about what a colossal asshole you were. The biggest.
      Some people are fundamentally incapable of being liked. It's not their fault, it's the way they're built. If they knew how to be loved by strangers, they would be. You can't tell these people to snap out of it, to shape up, to just change how they work. You may as well ask them to grow another finger. (Which they'd no doubt thrust upwards while telling you to fuck right off, you fucking asshole.)
      All those years you spent with the dearest ones in your life are gone, gone, entirely gone and never coming back. No matter how much you loved her, no matter how much you hated the way she looked when she was drunk, again, and smashing one more thing. No matter how rich her life, or stupidly tragic her alcoholic, angry, death, no matter the stories you could tell, the stories she told, the things she did, every single glorious instant of bright possibility and the declaration that this, now, is truly living, no matter all that, those are only memories, and not the thing itself.
      But somebody might notice, if you write something. If you make something. If you say something. If you sing something. If you paint something. If you run all the possible things through a blender, until every single motion is art, every breath, every thought, every touch, every glance, every single possible thing, every moment is life, and then put it someplace someone might see, then at least you are trying.
      That thing you are making now, right now, right this instant, that is the only thing that matters. The present is the only thing that could possibly matter, it's the only thing that exists. The future is hope. The future can only ever be hope.
      An AI can out-paint, out-play, out-write, out-code, out-anything a human being, if not now, then next year. There is literally no point in attempting to create anything yourself, because the future is going to be custom-built entertainment jammed right into your eyeballs and earholes. This is the future of the human race.
      If you've taken psychedelics, you are familiar with the sensation that you are the instant representation of the universe experiencing itself, and that each and every wonderful, wonderful person that ever lived, and every squirrel, and every tree and nut and twig and bud, every smallest and largest thing, is just one particular way of being, and this is how we all are. AI is that, just faster. The universe is telling all the stories, all the time, all at once, and no individual revelation can be any more, or any less, than just that which it is.
      So I am watching TV, as my ancestors did, and my descendants will, and the stories we tell are only stories, and the things we build only things, and the people we knew, only wonderful, wonderful, wonderful, and we miss them so, so much. And I am writing while I watch TV, because you never know, someone might notice.
      The future is always hope. Always.
    This is not a love story
      (3 min read)
      I picture myself:
      The wind snaps rain around my head as I stand at the edge of a field. It is late afternoon.
      I have been here since dawn.
      Why have I come here?
      I am looking for green, I tell myself.
      (What is green?)
      My head is full of story. I look at the clouds, watch the lightning, hear the thunder. Dragons play in the sky today—dragons breathe fire in my eyes.
      My eyes are alive with story.
      She is there. Tall, dark. Her name is—
      No matter. She is there.
      "Look at yourself." I look.
      "You're a mess," she says. It's true. A part of my mind registers my appearance: wind-blown, dirty, wet. The rest of my mind…
      The rest of my mind wants to tell us all a story.
      "Let me tell you a story," I say to her.
      "What are you doing here?" she asks, ignoring me.
      "What are you doing here?" I reply.
      "I came out to see where you'd gone. I've been waiting for you to come back inside."
      "Let me tell you a story," I say.
      "Can you tell me inside by the fire where it's warm?" she asks.
      "No," I say. "Let me tell you here."
      She shrugs and hugs herself. "Go ahead," I hear her say, but my head is full of story, and I am already telling:
      "A man at the edge of a field.
      "She is there with him. Rather, she accompanies him. She is not 'with' him, cannot be, because his mind is full of story. What he is seeing, what's happening in his head, has nothing to do with her—it has everything to do with her, but she doesn't know this.
      "She sees only a man at the edge of a field." I pause.
      "Is that all?" she asks.
      "So far," I say.
      "Is that us?" she asks.
      "Perhaps," I say, with a small smile.
      "And your head is full of story?" she asks.
      "Always," I say, and turn away. She doesn't say anything more so I begin walking toward the center of the field.
      "Wait," she says. I stop and turn to look at her. Tall, dark, lovely. Eyes dark, a glint of passions at the center. Hair long, brown, wet from the rain. "Isn't there any more?" she asks.
      "I don't know," I say. "Is there?"
      "It's your story," she says.
      "Yes, it is my story," I say. I look through her boots flecked with light brown mud for a minute, and then continue: "The man wants to tell her what he's thinking. He wants to tell her of the story in his head. He wants to tell her all about the thousands of dragons he would slay for her. He wants to tell her of an old brown house, and a man and a woman, and their dog. He wants to tell her about the fire he sees in her eyes. He wants to tell her how he remembers seeing a sunset with her, from the top of an old carnival's ferris wheel. He wants to tell her about how, when he was seven, he caught tadpoles and put them in a jar.
      "He wants to tell her all about love. But all he says is 'Hi,' with a small smile.
      "'Hi,' she says, and kisses him."
      The lengths a man will go to win a woman's heart! Here I have placed myself at the edge of a field, standing with a beautiful woman. I am telling her a story about a man who wants to tell the woman he is with how he feels for her.
      I am hoping that she gets the point of my story—that she would smile for me with her eyes of brown fire, and kiss me.
      She smiles.
      "Hi," she says, and kisses me.
      I picture myself:
      I am standing alone at the edge of a field.
      Why have I come here?
      I don't know what I am looking for, I tell myself.
      She is not there. Tall, dark.
      I miss her. Her name is—
      No matter. She is not here.
      The lengths a man will go to win a woman's heart—
      —I have yet to meet this woman, and already I miss her!
      Strange life is.
      I picture myself:
      I am writing alone at the edge of a field.
      Why have I come here?
      I know exactly what I am looking for.
      She is not here. Tall, dark. Her name is—
      No matter. I will find her.
  September 18
    I'm not sure having the blog part has been good for me. When I started, I just wanted to build a place I could post my work. I've come to realize I'm not that special, and the things I make aren't really very good. This is something we all have to come to grips with, eventually. There are very few successes. One shelf in a used bookstore holds more talent and broken dreams than any one person can have, and the shelves just go on and on. Having a place to put my thoughts means evaluating every thought—shouldn't I turn this into an essay? The pressure inside my head is relentless, the tinnitus has been screeching at jackhammer levels for weeks. And it's no fun anymore to try visual things. The AI can trounce me instantly, all day long. Everything I make is unique, like a snowflake, and about as useful. I never had anything good to say, anyway. I will probably continue writing and trying to make things but that is only because I can't help it.
  September 17
    I'm bored and part of the reason I have the blog part is to post old things. So here's another one. I can't decide if it's untitled or not.
    as yet untitled
      Oh, the drunken pheasants!
      I would like to fill the pockets of my great long coat
      with brown birds snoozing away
      and trudge home beside him
      boots crunching the frosty mud
      Finally reaching the fence bordering between safe and adventure
      "A good night's work, eh?"
      leans and lights the pipe that he has been treasuring
      His kind eyes, mischief and love and
      it's been so long since i felt
      so safe
      so happy
      so cold
      Let's get some cocoa
      And don't tell your mother
      ~
    Here's another story about bears. This one could probably be longer, but it's a start. (Illustration by DALL-E)
    My friend the bear
      (1 min read • Illustration by DALL-E)
      Just the other day, not so far away from right here, there was a little boy who got lost in the woods. But he wasn’t scared, because a BEAR saved him! This really happened. Everybody was talking about it. A little boy, saved by a bear.
      Now, some time after the boy was saved by a bear, everybody had moved on to other amazing stories about bears and what not. And they forgot about the boy who was saved by a bear.
      But the boy never forgot, of course. He thought about his friend the bear every single day!
      When the refrigerator door was left open and all the ice cream melted, that bear saved that little boy again.
      When the little boy couldn’t find his jacket and they were running late, the bear once again saved the boy.
      At the zoo, the bear saved the boy, wrestling an elephant before the boy could get trampled!
      Stuck in a tree? Not with that bear around. And when the boy threw a ball up on the roof, who climbed up and saved that boy? That’s right, the bear.
      Several times, that bear saved the boy by fixing the internet.
      Saved from a math test? Boy plus bear equals A-plus.
      (The bear also saved the boy by hacking the security cameras during a heist, but that was years and years later, and really none of our concern right now.)
      But the boy most often appreciated when the bear would save him from another bath.
  September 15
    I will probably revise this next piece. But I like it as a first draft.
    Prompts
      (1 min read)
      a protagonist who has known longing, and come through the other side
      ten cats driving a bag filled with light and terror
      president pikachu giving a speech
      the secret to all creation, in crayon
      a photograph of a painting of a sculpture of an island in a lake on an island in a river on an island in your heart
      something that will trend on instagram and make me famous
      california california california california california
      that sky
      the sound of the universe in the next room
      that place we never visited
      ~
      in gouache, acrylic and oils, on glass, lit by fire from below
      on cardboard, halftone, sepia, purples and oranges
      framed, in a gallery
      on a postage stamp on a postcard from
      without regard for proper perspective
      tattooed on the belly of a whale
      on a milk carton
      in blood on a mirror
      with light exploding from inside like the fireworks of a sun
      as the logo for that which will dominate humanity for a thousand years
      in cotton candy, daffodils, butterflies
      ~
      without faces
      with cats
      as a musical comedy
      with tragic consequences
      enabling us all to fly
      without fear
  September 14
    I added a DALL-E illustration to the tribble thing.
    Projection and fantasy
      (5 min read)
      Back when Google maps was a thing you used on a web page and phones still had buttons, I used to use "how would you implement Google maps" as an interview question for software developers. There's lots of places to explore how someone approaches problems, when the stack goes from the browser all the way to satellite imagery. And it's something most people had used at the time but hadn't thought much about precisely how you could make one of those yourself, and the problems you'd need to solve.
      I prefer interview questions that touch on subjects that are actually likely to come up in the job, so at that time, unless I'm working at Google or Microsoft, this is a really unlikely problem area to actually come up, right? For instance, I was interviewing candidates to work on the software development team for a tabletop roleplaying game company—you know, lots and lots of dice, and rulebooks with hundreds of pages of tables on how to be an elf. So really, the whole "how would you build Google maps in a web browser" is more akin to "How would you build Flickr?", which was one of my other go-to questions in those days.
      Except... Earth isn't the only planet people might want to explore via an interactive map. If you have a tabletop roleplaying game, you need a setting, a default place where all the rules take place. If your game has elves, then you need to explain, in one form or another, why it has elves and what they're up to, generally speaking. It's up to the players to make it happen, and there is one player in particular, the one that runs the game, and controls the non-player characters, like monsters, who generally shapes the world and the narrative.
      But to explain the rules, you need a setting. And before you know it, you end up with an entire planet full of continents and oceans and countries and rivers and cities and mountain ranges and seaports and deserts and landlocked seas. This helps you assign projects to freelancers, because now you have a shorthand ("put it in the desert kingdom that's like Egypt with dragons"). And players like it too, because in addition to your rules, you also publish adventures. These are prebuilt set pieces, which you can combine and present to the players, with plots, maps, monsters, memorable characters, etc. If people like an adventure, you can set more adventures in the same area. Entire series of adventures may have the player characters roaming to and fro across an entire region, handling conflicts that involve the leaders of entire nations.
      These adventures need maps. You don't strictly need the maps for the basic setting for the game rules, because the presumption is that the players can make their own maps. But once you publish an adventure, you need to provide a map. And if you're publishing an entire series of adventures across an entire region, you need more maps, that cover larger areas. Naturally you are also collecting these maps into other products such as "guide to the region of the record-collecting ants", which means more maps.
      These maps are made by cartographers, but they're not ordinary "practical topology"-type cartographers. They're visual artists, more akin to illustrators. They typically use Photoshop or something like it, though there are some tools aimed at making it easier to work with gridded layers, repeating textures, landscape generation, etc.
      Practical topology-type cartographers have extremely specialized, extremely mathematical software tools, and enormous databases of mapped points. It's an extremely rigorous field, these are the sort of people that would really prefer if everything had sixteen places after the decimal, and put careful thought into picking the projection they're going to use for basically any map, even one that's just a few miles across. Because it turns out, that's enough to actually warp the surface of your map enough that you have to take it into account when drawing a diagonal line from one corner to the other.
      I actually had a couple different use cases for the Google maps question, but the obvious one is: Let's make a Google maps for our default setting. Which, come on, super awesome to have. Of course, there's a lot of ground to cover on an entire planet, so you might not have great maps of the entire thing. But let's say you have enough maps to cover the important areas. The next step is, take all that "satellite imagery" and rescan it at varying resolutions, and then chop it up into little square tiles that you can swap in quickly. That way you don't have to download the entire map, just the portion you can see.
      The other use case I had for this technology was, take the map of a dungeon, and zoom and tile it for use in a virtual tabletop. The virtual tabletop takes all the game stuff and jams it into a web browser. In this case, since we have print-resolution maps, we can zoom up to 8 steps, from the overall view of the market square, down to close enough you can literally see the individual illustrated fruit in the carts. This actually worked ridiculously well, and later I adapted the same idea for rapid-viewing individual pages of a PDF. For that, of course, you want a straight one-to-one projection, because you are mapping a plane to a plane. Not a sphere to a plane. So the mapping you choose for presenting a tactical map of a dungeon is the same for the printed page: No warping at all, because the source and destination are both flat. Just scaled differently.
      But for Google maps, you absolutely need the projection, because the thing you are displaying, and the thing you are projecting it onto, are two different shapes. And, because humans are awesome, we know to do things like adjust differently because the Earth bulges out a little bit at the equator. But we'll ignore that for the imaginary world.
      Guess which kind of cartographer doesn't actually use projections from a sphere to a flat space when drawing maps of large portions of a globe? Right, people doing what they're supposed to, which is make things people want to pay money for. These maps look fantastic on the printed page, or vinyl map, or poster, but they're not really practical topography...
      Anyway, all that map-related stuff got set aside for other priorities, but to do it properly for an imaginary planet, from a bunch of flat maps, you need to do the exact kind of map projecting that you get with the Mercator, except backwards.
  September 13
    Some days it is too hard to write something new, or even type up something old. So instead, here's some more art.
  September 11
    The wire. Illustration by DALL-E for the second Mars piece.
  September 10
    This time I let DALL-E handle the illustration for the ballad of Arnold Hacks.
    I added art to The Aeronaut. I'm sure an AI could do better, but some things I'd rather do myself.
    This next piece has had a number of different titles. It started out as "The Ballad of Arnold Hacks," but it's always been a story for spring.
    The Ballad of Arnold Hacks (a story for spring)
      (5 min read • Illustration by DALL-E)
      And sat down to breakfast: toast with butter and strawberry jam; and scrambled eggs with a touch of basil; and orange juice from a concentrate.
      Arnold Hacks looked out the plate glass sliding door of his apartment at the city below, and pictured the people going about their business like the tropical fish in his aquarium. He saw them dart back and forth, pausing at one door, rushing to the next, all dressed in gay colors, all the colors of the rainbow, all the colors of Arnold's fishtanks.
      Arnold Hacks smiled, and picked up a slice of toast, buttered it, spread some jam over the butter, and took a bite. He enjoyed every sensation the toast brought him: the slightly dry edge that was the crust, the cool taste of a piece of unmelted butter, the intense sweetness of the strawberry jam. He chewed, marveling at his teeth and his tongue, the amazing crescendo and decrescendo of sensation that was dry buttered toast with strawberry jam.
      Arnold Hacks looked at his fishtanks blankly, seeing not tropical fish and pebbles and a bubbling pirate ship, not seeing the metal hood covering the fluorescent light or the glass walls of the tank. Instead, he saw the world, the universe enclosed within a fifty-gallon fishtank. He saw friends and strangers ten thousand miles away slipping back and forth through tiny coral reefs. He heard the music of four billion souls making love, and the sighs of four billion souls passing on into eternity.
      Arnold Hacks pushed his chair from the table and walked over to the fishtank. "Hello, goodbye, my friends," he said. He knelt before the tank and put his face to the glass, cool and smooth on his cheek. He tapped ever so lightly, and smiled the smile of a soldier who has had a wonderful leave, but must now return to the front. "Goodbye, hello, my friends," he said.
      Arnold Hacks cleared the dishes from his table, enjoying the cool porcelain on his fingers, and put on his shoes, enjoying the warmth of the wool socks on his feet, and the sound his shoes made when he walked on the linoleum in the bathroom to brush his wonderful, wonderful teeth.
      Arnold Hacks went to work.
      ~
      And sat down to breakfast: Cheerios with milk and a teaspoonful of sugar sprinkled on top; a banana; and coffee.
      Arnold Hacks looked through the curling black bars of the railing along his patio, and saw the city. He saw millions of people flitting hither and yon, like the birds in the aviary in his living room, all dressed in their flashy plumage like rare, exotic birds, in all the colors of Arnold's birds.
      Arnold Hacks ate his cereal, enjoying the slightly metallic taste of his spoon; anticipating the fuzziness the banana would bring to this mouth; tasting the bitter heat of the black coffee.
      Arnold looked and saw his coworkers at the fabric store in his aviary. They flitted back and forth, chirruping noisily about this and that, communicating nothing of real substance; not that it mattered. He listened to the song of his birds and smiled. "Hello, goodbye, my friends," he said, and waved to the birds. He stood up from the breakfast table, walked to the birdcage, and placed his fingers on the bars. He smiled the smile of a small boy who is leaving his family for summer camp, alone, for the first time. He whistled a low, soft, warbling whistle. "Goodbye, hello, my friends," he said.
      Arnold Hacks cleared the table and washed his dishes, loving the feel of the sudsy water on his wrists, the little soapy bubbles clinging and popping wetly. He felt the chilly air from the refrigerator as he put back the milk, and the cardboard of the cereal box on his fingers.
      Arnold Hacks went to work.
      ~
      And sat down to breakfast: a bagel with margarine and cream cheese; a glass of low-fat milk; and the morning paper.
      Arnold opened the paper and looked at the world. He saw the billions of souls of the earth scurrying across the white pages like tiny black ants. The words on the pages formed a worldwide colony of ants, each tumbling over the other in a rush to get to the goal and return with sweetness. Sometimes they cooperated; sometimes they hindered each other's progress toward the prize they all sought.
      Arnold Hacks looked down at the line of ants in his kitchen, and saw the world. "Hello, goodbye, my friends," he said. He got down on his knees and placed his face near the floor, enjoying the feel of the grit from the floor on his cheek. He watched the ants rush to and fro, and smiled the smile of a man leaving his family whom he loves very much. "Goodbye, hello, my friends," he said.
      Arnold Hacks got up from the floor and brushed the crumbs from his cheek. He put on his tie, enjoying the feel of silk running through his fingers and the slight pressure around his collar. Arnold Hacks hummed the song of the earth, the song of the ants.
      Arnold Hacks went to work.
      ~
      And came home.
      Arnold Hacks loosened his yellow silk tie and closed the door to his apartment.
      He made his way to the bedroom and carefully removed his clothes. He hung the coat and tie and slacks in the closet, and dropped his socks into a pile of clothes on the floor by the bed, letting the worries of the bank slip from his shoulders with his suspenders.
      Arnold Hacks walked into his kitchen naked, feeling the cold linoleum under his feet. He knelt down and looked at the rushing, bustling, stumbling line of ants.
      Arnold put his face to the floor and got in line with the rest of the ants.
      As his forehead touched the floor, hard, powerful pincers formed. A gleaming black shell covered his body. He became very small.
      "Goodbye, hello, friends," he said as he joined his people.
      ~
      And came home.
      Arnold Hacks closed the door to his apartment. He pulled his shirt over his head as he walked slowly to the bedroom. There he continued undressing, adding his clothing and the pressures of the fabric store to the pile on the floor by his bed.
      Arnold Hacks walked back to the living room naked, hardly noticing the wonderful sensation of evening air on bare skin. He stood next to the aviary, listening to the chattering and warbling of the beautifully colored birds.
      Arnold Hacks opened the gate and got into the birdcage with them.
      As his hands passed the metal bars they turned to wings. His face became a beak, and brightly colored feathers rushed to cover his body. He became very small.
      "Goodbye, hello, friends," he whistled as he flew into the air to join his people.
      ~
      And came home.
      Arnold Hacks closed the door to his apartment and turned on the light switch. He reached down and took off his shoes, and walked to his bedroom. There he continued undressing, carefully dropping his clothes by the bed, leaving the anxieties of the working world in a pile of clothing.
      Arnold Hacks then walked back to his living room, naked, and stood by the tropical fishtanks. He sighed, and watched the fish, the gaily colored fish, dance and dart and swim.
      And then got into the tank with them.
      As his feet touched the water, they turned to a tail. His hands became fins, and shimmering brightly colored glistening scales rushed to cover his body from eyes to gills to fins to tail. He became very small.
      "Goodbye, hello, friends," he said as he slipped into the water to join his people.
      ~
      And now you know.
      ~
      1985 • First draft
  September 9
    I dug up a bunch of old stories from storage, stuff I haven't looked at in decades. Much of it I'd completely forgotten, others I remembered, but thought lost forever. I think I'll retype and post some of them here, rather than just let them languish. Many, many years ago I wanted to be a writer. It's not a lucrative occupation. I think I would have to move into a cabin in the forest, or a van down by the river, to make it work. I don't think anyone besides me would want to publish these pieces anyway. You'll see what I mean.
    The Aeronaut
      (5 min read)
      I am a thousand feet above the earth, standing on the woven wicker of my gondola. It is perfectly silent, and still, here. There is no breeze, for the wind pushes me when it pushes itself. I will stay here for the rest of my life.
      I am a thousand feet from the problems of others. There are no people here to command me, to draw me into their petty lives, their silly and pitiful problems. As if their problems were my problems. As if I had none of my own to ponder about, to worry about, to panic about. They think their problems are unique, special, important, worth thinking about. Problems are not expensive, fabulous toys for only the very rich. Problems are a dime a dozen, they are two for the price of one. They are on fire sale, losing our lease, all must go, inventory reduction, year-end close-out; they are free. But I have no problems now. I am in my balloon, and I am a thousand feet higher than the rest.
      My job was to shuffle things. I worked in a factory, shuffling colors bits of plastic and metal, inserting them into the proper holes at the proper times. I moved through mazes to get to nowhere in particular, for any place in my life was as good, or bad, as any other. I did not understand the purpose of the things I did. I saw no reason for the insertions and movements. I simply did as they told me, performing the proper tasks at the proper times.
      I worked in this factory of tedium for twelve years. I came in search of a job, a way to add meaning to my life. I had no particular reason to live then, and my superiors in their clean clothes gave me work. I enjoyed it for a time; at the beginning there was variety, even interest. I had to learn a new language, filled with obscure technical words, so that I could express myself in new and complex ways. There was a challenge to this, learning to speak a language different from the one I grew up speaking, just so I could communicate with my superiors. But after I mastered it, they ceased congratulating me on my progress, and I ceased to find anything of interest in their incessant, irritating demands.
      I shuffle the colored bits of plastic and metal no more. I have neither with me here a thousand feet above the factory where I worked. I used to make empty gestures and meaningless motions, but no more. I am a thousand feet up in my balloon because I do not wish to live on the ground any longer. I will stay up here, living quiet and unobtrusively, forever. I have food enough for the rest of my life. I have a sandwich and an apple.
      ~
      I have never understood my superiors. They came round wearing fancy coats and black-rimmed glasses and balded heads, saying things that were incomprehensible to me. I understood only that they were testing me. To be sure, they called it being gainfully employed, and I suppose work there was better than living in a box, or sleeping under bridges, but I did not enjoy it. They taught men to shuffle and stuff and place and insert and speak, and come when called, and listen with attention—and fear with reverence. They do not explain, but I am sure they do not know if I have a soul.
      I do have a soul. The others, they doubt, they question. That is their job, I suppose, determining whether I have a soul. I think that is their job, because I cannot see any other pattern to the work they make me do. I had to do as they said, when they said to, in the precise manner they indicated. They gave me ridiculous tasks to perform, to no apparent purpose. They explained nothing to me.
      It is a silly task, determining whether I have a soul by making me to lie down and get up and work and stop working at the clangs of bells and the flashing of lights. They should have asked. They should have asked me, the one they are testing, whether I have a soul or not. It is my person, after all, and I ought to know. Of course I have a soul. They should have asked, but they did not, and they have lost their chance now. I am a thousand feet above them, now, and I am not going back.
      They should have asked me. I would have told them. After all, am I not a reasonable person? Can I not converse with them, speaking clearly, giving complete answers to simple questions? But they did not ask. I do not think that they would have believed me anyway, had they asked. They trust their machines, their instruments and testing equipment, much more than they do me. Can a buzzing, beeping, flashing machine have a soul, and answer truthfully? Of course not. But they still trust those articles of science, those boxes and dials and counting screens. My superiors trust them, and do not ask me. Sometimes I wonder if they have souls.
      ~
      I will finish my sandwich, and my apple, and then I will be finished. It is silent up here in my balloon, and the quiet has allowed me to think in peace. I am in my balloon because I am going to stop worrying about the things other people put on me. I am going to do exactly what I want, precisely when I want to do it. I will no longer spend my life waiting for the ticks of someone else's clock, watching for my chance to get away from my work for a short time. I will work when I want, play when I want. This is my life, and my body, and my spirit, and my soul, and I will use each of these exactly as I please.
      I will eat my sandwich, and my apple, and then I will be finished. Then I will once again join those on the ground, a thousand feet below. But I will let the balloon stay up here, I think. The balloon, it is silently joyful, being up here in the sky a thousand feet above them. I will let it stay, and be happy, and I will go back to the earth, a thousand feet below.
      ~
      PALO ALTO (AP) — Fletcher, an experimental chimpanzee at the Stanford Animal Research Laboratory, was killed in a fall from a ballon yesterday afternoon. A spokesperson stated that the animal had escaped from its cage, and hid inside the gondola of a weather balloon moored to the roof of the Natural Sciences building. The forebrain-enhanced chimpanzee managed to untie the balloon, allowing it to rise while still inside. The animal then panicked, and fell out of the gondola to its death.
      ~
      23 December 1985 • Third Draft
  September 8
    Some of my ideas just make me laugh. Here's one: D'ominous—dominoes that go "dun dun DUNN" when you play one.
    I want to know what the rules are so I can be safe. Not to skirt them, or break them, or test the boundaries. I just want to know what the rules are that will keep me from being punished. The rules tell me what I am permitted to do. I do not want trouble. I want safety.
  September 7
    I've figured out where the Mars thing is going. See this paper, and this graphic novel (which actually features me as one of the characters), for background. I kind of want to do it as a graphic novel, but getting an AI to be consistent from one illustration to the next is extremely challenging. Maybe I should just try to work with a real person instead of doing everything all by myself, like a stubborn four-year-old.
  September 5
    So far I've made more than 200 illustrations with DALL-E for the Town of Bears. I'll probably end up using maybe a dozen or so. There aren't any roller coasters in the story, but this picture makes me want to write one in.
  September 4
    I added a DALL-E illustration to the first Mars piece.
    Working with an AI is a great way to re-evaluate the relative worth of the effort put into any individual creation. It's freeing, and intimidating. I've gone through dozens of images in just a couple days, simply getting a feel for what DALL-E can do. The PDF linked here gives a pretty good overview.
  September 3
    I added art by DALL-E to the first days of the Biden administration. I like the way all the days look, but day 6 may be my favorite.
    I asked DALL-E for Bigfoot lurking in the produce department. Cannot stop laughing.
    I ended up going back and giving this next post a title anyway, just to be sure.
    Why write
      I've cut back my reading to almost nothing, but I still like to look at Andy Sylvester's river, which is where I ran across this piece by Ken Smith, titled "Why Write?" I liked it, a lot, and not just because I love rhythmic presentation. My brain applied a spoonerish rearrangement to the closing sentence, though, so it read: Writers leave a trail of marks down the page in their hour of need that others might be able to follow.
      I can't decide if that's an improvement, or just the usual writerly self-absorption.
      ---
    I wonder what a multi-node untitled post looks like, in a river, in NetNewsWire, on my webpage. Let's find out! (This is not that post, this is a normal untitled post.)
      This is a post with an untitled node with no special type, and a couple subnodes.
      This here is the second subnode. I can't decide if it's going to look like an indented outline, or maybe it will look like three paragraphs in a row.
      Hence the experiment.
    Looks like the experiment worked OK for my RSS reader and the website, but the post doesn't show up in the river. I've decided I like being able to write untitled posts, a lot. But I think I want them to show up everywhere. Untitled posts are kind of a pain with rivers, because unless you keep them extremely short, people have to click through to read the entire thing. For some reason, clicking on the title of a post in a river to show/hide the post seems less intrusive than having to click through to another website. It's the same number of clicks, how could that be? Metrics aren't the only thing, I guess.
    Joke is on me, I should be patient. The multi-node post shows up mostly OK in the river. There are no line breaks, which is unfortunate, because I care a lot about that. So I dunno. (I should fix my own CSS, of course, because untitled posts look like sequential paragraphs on the website. Always something in the way…)
  September 1
    I added a DALL-E illustration to The Contraption.
    I added a DALL-E illustration to the interdimensional time travel party.
    Welcome to Mars, III
      (1 min read)
      OK what do we got. Christ. A first-timer. Shit. Forgive me. Set and setting is important.
      Not that we get that here. Fucking assembly line. I did not train for this. I'm sorry. I will try to take it easy on you. But it will not help.
      First off, you wanna do a line? We got meth, we got coke.
      Did they tell you we don't have that shit here? Yeah. We got it. Any time you like, we got fucking kilos of it. I'll give you a sack for after work, if you want. Nobody ever does.
      Thought you'd be working in the mines or something? You don't have the slightest idea what you're doing here, do you. What Mars is all about. No, I am not going to tell you. You're a first-timer.
      But first, yeah, do the line. I'll get you some valium for after. But we need you fucking sharp for this part.
      There. Better? Good.
      I am going to tell you a number. You will memorize that number.
      Here is the number: ONE TWO TWO THREE THREE THREE
      You got that? Good. We pick these so you don't need a good memory. Tell me again. Good.
      This will pinch a little. There. You are juiced up and ready to go.
      You got about sixty seconds. This next part is going to get a little weird. There is no way to prepare you.
      You ever trip? Doesn't matter, wouldn't help. Used to think it might. Makes no difference. Either you make it, or you don't.
      Just don't fucking forget the number. Tell me again. Good.
      Now, tell it to whatever greets you. See you in fifteen minutes.
      Part I ~ Part II ~ Part III ~
August 2022
  August 31
    I don't know if it's possible for me to write something that isn't horrific and alienating. Maybe my writing is just broken.
    Someday someone is going to find the blog part and read it and enjoy it and tell others they like it. Anyway, here's some more art.
    Welcome to our interdimensional time travel party!!
      (2 min read • Illustration by DALL-E)
      We will have already been getting this party started!
      We have always been getting this party started!!
      Let’s already begin having gotten this party started!!!
      ---
      IT’S PARTY TIME!!
      IT’S PARTY TIMES!!
      IT’S PARTIES TIME!!
      IT’S PARTIES TIMES!!
      ---
      DO NOT STOMP THE BUTTERFLIES
      ---
      BYOLN
      Bring your own lotto numbers
      ---
      Parallel dimension versions welcome
      Please follow goatee safety guidelines
      The I you save could be your own
      ---
      Remember where you parked
      Many time machines look similar
      ---
      If you have opposite chirality and/or are antimatter you may be asked to party in a different location
      If you are fictional please wait for assistance
      ---
      If you don’t find your question here, please check back the day before.
      ---
      Don’t fuck yourself
      Or your grandparents
      Go fuck yourself
      Or your grandparents
      ---
      Already have plans? / have to be somewhere else that day?
      Tell paradox to screw itself
      ---
      If you expect in excess of sixteen of yourself to show up, please exercise appropriate precautions as this is over the level at which any two of yourselves will start making out with each other (ie the shatner limit).
      ---
      Please don’t just shave your goatee halfway through the party and pretend to be your non-evil twin.
      ---
      If you are from a time more than sixty thousand years out, please remember to adjust coordinates to account for precessing on earth’s axis
      ---
      Plug in recharging available. Some nuclear fuel may be available depending on season
      It is normal to experience higher than average déjà vu, as there will have existed a locally heightened irony index
      ---
      No refunds
      Just go back and don’t buy it this time
      ---
      Ride sharing encouraged
      Bring a newspaper or tablet to demonstrate the date you come from
      Set your clocks to party time
      ---
      We can’t all kill Hitler
      But we can all party!!
      ---
    Here is some art that I am putting here because I like to look at it.
    Starting to realize that the reason nobody believes in me is that I am simply consistently wrong about everything. There's always a reason, you just have to figure out what it is.
    I take literally everything personally, and I am aware that the entire world does not actually revolve around me. So I apply mental filters to everything: This is not actually about you. I remind myself of this, constantly. As a result, I can only tell when something is actually about me if someone actually mentions my name, or refers directly to my work, or contacts me directly.
    I love this post by Andy Sylvester. It made my day when I read it, and I still think about it days later.
  August 30
    The blog part is basically a continuous lesson in getting over myself.
    Here's some art that I am putting here solely because it makes me smile.
    I don't understand anything about how people work, so here's a story about bears. It's mostly true, probably.
    Town of bears
      (3 min read)
      Just last year, far away in a small town called Luchegorsk, all the people were enjoying the last days of summer.
      It was late afternoon, and Nikolai stepped outside to walk his fluffy grey cat.
      Suddenly, the air was filled with barking. It was all the dogs in the town, making such a racket!
      "Those dogs are going crazy," Nikolai thought. "Wonder what they smell?"
      Nikolai turned around, and there it was: a big black bear, right in front of him!
      "I'd better pretend to be bigger than that bear, and back away slowly," Nikolai said to himself.
      When Nikolai was safe back inside, he called his neighbors to tell them about the bear.
      And when they heard about that bear, his neighbors called their neighbors.
      Soon everybody in town had heard about the bear.
      While the townspeople were talking about the bear, the bear was talking to her bear friends about the town she'd found.
      There were so many garbage cans and dumpsters full of food, every bear around could eat their fill.
      So the bear and her friends came back to town, and had a grand time.
      They found garbage cans full of food, swimming pools to splash in, and entire buildings full of delicious things to eat.
      They even found trampolines, and jumped up and down on them so high in the air that even the people marveled at the bears.
      At first, people loved having the bears around.
      People took selfies with the bears, and some fed the bears, and some even tried to ride the bears.
      (This did not end well for the attempted riders.)
      People sang to the bears, and some say the bears sang back.
      But eventually the townsfolk grew tired of the bears, and wanted them to leave.
      And everybody had an opinion about what to do!
      Some thought they should feed the bears.
      Others said that's no good, we ought to pack them into crates and mail them far away.
      Still others were positive that a bear cavalry would be useful one day.
      But nobody could agree on a plan, so they did nothing, and the bears kept coming.
      "What can we do about these bears?" everybody cried.
      Some suggested painting the bears white, and driving them to the north pole.
      Some thought they should talk to the bears, and ask them politely to leave.
      But still, nobody could agree on a plan, and so the bears kept coming.
      Eventually there were so many bears around that nobody went outside anymore.
      Nobody tended their gardens.
      Nobody went to school.
      And nobody delivered the mail.
      "This is too much!" the townspeople cried. "They don't have any bears in that town down the road, no bears at all! Let's move our town there."
      So all the people in the town gathered everything they owned.
      And one night when the bears were all soundly asleep, all the people of Luchegorsk just up and left.
      Later, the townspeople would remember the bears with fondness, and share stories about the bears and their antics.
      But none ever went back to that town, for it wasn't their town anymore.
      It was the town of bears.
    Welcome to Mars, II
      (1 min read • Illustration by DALL-E)
      Hey, it's nothing. Look, right there, at the base of my skull. No, it doesn't hurt going in, what the fuck? You stupid, or something? I know you're not stupid.
      Did they give you that same horseshit about "the wire's a thousand a minute and don't start"? Of course they did. Nobody's ever started before they get here, I tell you that. They got cocaine, and DMT, and all the mushrooms and meth and weed and molly and whatever the fuck else you need back home.
      We don't got none of that here. What we got, is the wire. And you don't need nothing else.
      Yeah, it's a fucking thousand a minute. You say that like you got anything else to do with your musk. What are you gonna do with it, buy a ticket back home? Fucking hell newbies. You are never, ever going back home. You are going to die here. And Elon isn't going to care one little shit, no matter what that asshole says.
      Look, why would I, a distinguished and accomplished individual such as myself, take the wire? Why would I spend a thousand a minute on something like that? What kind of experience could you possibly have, that could be worth so much?
      What do I know that you do not? Ask yourself that.
      Think on it. Come back tomorrow. I'll be here.
      Part I ~ Part II ~ Part III ~

    On the ranch
    A hand-raised, well-loved tribble cooked over an open fire? That's just heaven.

      (2 min read • Illustration by DALL-E)
      "Everybody loves McTribblets, and why not? They're great. But a hand-raised, well-loved tribble cooked over an open fire? That's just heaven."
      Mike Sern isn't exaggerating, and he should know. For the past 90 years, his family has specialized in raising tribbles at Tribble Barrel, their ranch tucked into the foothills of the Sierra Nevadas in northern California.
      What's the special touch that keeps celebrities coming to mingle with the locals for a taste of what Gourmand famously described as, "like fucking with your mouth"?
      Mike says his family's secret is the orphanage.
      "Everybody's got tribbles at home, but nobody ever eats those. Most feed tribbles are raised in factories with a basic level of comfort. The meat's good. But like the joke says, it does taste better if you play with your food."
      In addition to making great pets, every tribble was specifically engineered to be a perfectly nutritious food, delicious specifically to humans—and to enjoy both being loved, and being eaten.
      Mike says the tribbles want both. "A great tribble, you know, it has to be loved. Only then does its true essence, its perfect fit with the human desire for eating really come out when it's served."
      Mike recognizes that part of the appeal of ranches like his is the still mildly taboo thrill of eating a creature that was somebody's pet.
      Sandi Gupta, a recent visitor, sums it up: "You feel a little guilty, I guess, because you know a child cuddled with it. But when you bite through that crispy skin on a fresh roasted tribble, all you can think about is how wonderful it is that this creature ever existed. And how incredibly suited they are to being both loved and eaten."
      The kids at the orphanage love to eat tribble as much as anybody.
      "My favorite is triple tribble time," says Nicky, who has been at the orphanage all of her five years. "We get to bring our tribbles to the cafeteria and sit with them. They're nice and purry."
      At the end of the meal the children bring their trays back to the counter, and giggle when the newborns squeak as they're scooped into a bin for later sorting.
      "Most tribble is just OK," says Mike. "Usually you don't have any idea what you're really eating. Those little guys will eat anything, including garbage. They make literally any food source completely safe and delicious to eat. But they taste even better if you skip the really toxic stuff."
      These days nearly 85 percent of the Barrel's sales are certified natural genome.
      Natural tribble sashimi is especially prized, and Oskar Hardor, recent Quatro Chef, is an expert at extracting the most delightful chunks of the freshest possible tribbles.
      "I love the Paibalds. They show you exactly where they want to be cut, in the pattern of their fur. They're ridiculously tender where they want to be, and the other varieties of flavor and texture they offer are incredible. It can be like a sweet, meaty melon or a fluffy hot spice cloud." Oskar waves his hands excitedly.
      "You want them purring," he says. "That's when you know it's exactly perfect."
      Tribble Barrel, $ $ $ $, lunch 11–4, dinner 7–11. Reservations recommended.
  August 29
    Building the safest place
      (2 min read)
      I am terrified of being noticed.
      I am terrified of being noticed, in the same way, in the exact same way, that a small child screams in terror, at the crack of the leather belt, coming closer. This is not the first time, it is never the first time. You cannot hide from this, but you will try.
      I am terrified of being noticed, exactly like that.
      You've never heard of me, because to be noticed is to dare irony to bring down punishment for having even tried.
      This can lead to things like never asking people really important questions, in all sorts of areas of life. If you've heard of ask versus guess, I am firmly guess. Because asking means finding out for sure what is coming.
      I don't like risk, not one bit. I do not want to be rejected. When I was hired for my current job, almost 20 years ago now, my interview with the CEO started with: "So I'm told I have to hire you."
      Someone like me can spend a long time assuming that promises will be remembered.
      I am a perfectionist because I can see the flaws and I know everyone else can, too. And they will ridicule, and mock me, and it will be physically painful.
      This is problematic, if you want people to take your work seriously. Nobody can read what you never finish.
      So, I am trying, I am trying hard.
      I force myself to make my work as fast as I can, as messy as I can, as small as I can. Twitter and blog posts and terrible illustrations. I can tell I cannot draw. I am OK with that. I know I can write.
      And I have learned, that if I can just make something, then I feel better after.
      I write, the pain goes away for a little while, I write again. I know this is how addiction works.
      I'm OK with that, too.
  August 28
    I think I generate too much content, too fast. I've posted 5,800 words this weekend across a more than a dozen posts. There's no audience for that. But either I post, or I don't, and everything stops hurting so much when I post.
    The only one who should take any of what I write personally is me, btw. I put up pieces like this so I can read them and see just how terrible I am to myself. Your ideas are fine.
    Welcome to Mars
      (1 min read • Illustration by DALL-E)
      You'll be paid in musk. Cubic, water and cycling is fifty musk a day.
      Lose your card, five hundred musk plus fees, so get yourself a fake and carry that. They don't care which ID long as you pay.
      You a wirehead? Good. The wire's a thousand a minute base plus options, so don't start.
      Don't bother with comprehensive on your suit, if it's worth the deductible you'll be dead.
      But do take the gap insurance on the financing. You don't want to be upside-down on the only thing between you and the rest of the universe.
      Part I ~ Part II ~ Part III ~
    I added art to the Dinosaur Train thing.
    Why the blog part has such terrible art that I make myself
      (5 min read)
      It's been a long few days at work, mostly due to that pointless project I wrote about previously. But that seems to be wrapping up, finally, so I'll have more time to do things like make art for the blog part. Which, of course, is the least important part of the blog part, and the one I'm the least qualified to actually do.
      Why would I do that? Why not just use something I pulled off the web, or even better, something generated by an AI? It's not like I can draw, obviously.
      I've done lots of copyright things. I'm an owner of works generated as works for hire. I've created works for hire, owned by others. I've written and negotiated software licenses, with lawyers and everything, both the shrink-wrap kind and the kind where the other party can actually afford lawyers of their own to go through. I've dealt with joke exceptions, including a clause that explicitly defined "worldwide" to include the Earth and its satellites, excluding Mars and the rest of the solar system.
      (I've also had my work as a cartoonist syndicated in real, old-timey print newspapers. I've been around the copyright block, is what I am saying.)
      Of course, I've also spent most of my career in software development, software publishing, or the media industry, or all three at once, so I've also dealt with copyright from the publisher's side of things. Both from an internal perspective (are we using the right licenses for the software we're using, building, or both), and from the extremely important perspective of do we have the right license to publish what we're publishing.
      This is why I make my own art for the blog part. I want it to be extremely easy for me to know if I can use an image.
      You'd think that would be a pretty simple question for a stupid blog. It is, kind of.
      Here's my rule: Did I make it? Then it's OK. Probably. (I'll discuss the "probably" part below.)
      If I didn't make it, then I have to go through another rule, which is: did I pay someone to generate this as work-for hire, or did I acquire it via an explicit license? Then it's probably OK.
      For anything else, all bets are off. You don't know that you have permission to even post that image to Twitter, let alone use it on your blog.
      This is why I make my own art for the blog part. Number one, I am cheap. This is for reasons. (Salaries posted for listings like these are definitely not standard for the tabletop role-playing games industry. VC money is pretty sweet.)
      Let's talk about why I said that even if I made it myself, or paid for it, it's probably OK to use.
      How I made that image is as important as the fact that I made it.
      Even what that image depicts is as important as the fact that I made it.
      These are things that sound crazy, you've got to be kidding me. I paid for that illustration. I paid to have that picture taken. I took that picture myself!
      You have to pay extremely close attention the terms of the license. Even if you bought something as work for hire, you still do not have rights to do anything you want with it.
      When it comes down to it, what you actually own is what you can convince a judge that you own.
      Having a work-for-hire contract, or explicit license, is an excellent place to start. But it is not the entirety. You purchased a specific set of rights, some of which were not spelled out at the time, but which were commonly understood. These understandings can change over time.
      Even back when I built the panopticon I wrote about, we paid extremely careful attention to where we got the information we were recording about customers, and what we could reasonably do. For example, I decided against any web scraping. Just because you can grab a span of bytes from a web page does not mean that the owner of that information has given you permission to do anything with that data.
      Personally, I think that includes whether or not you can use that data to train an AI. Whether or not courts will agree, who's to say?
      But I bet that if I owned a bunch of data that I could prove made it into your AI, and it was worth it for me to go after you, I would probably do it. Because that is how copyright law works. It advances because people try to do things to make money, other people complain because that should be their money, it ends up in court.
      (If you are having trouble imagining how this might play out, imagine I am Disney, and you are training an AI to generate animated cartoons.)
      The reason this part even comes into play, is because that AI will at some point be making other works. And of course we want to know who owns the copyright on those works. "This is easy, because this is just science fiction about whether an AI can own a copyright," you say. Nope.
      Even if you say that a robot can't own a copyright, or assign a copyright, that still doesn't mean that whoever ends up owning that copyright will be able to do what they like with it. AI-generated imagery brings whole new "what is a derivative work" questions to the table.
    Eventually, you just tape a note to your keyboard so you don't forget.
    Your ideas are completely worthless
      (2 min read)
      Ideas aren't worth shit. Not until you do something with them.
      I once went through this at a party in the early nineties, with a guy who wouldn't stop going on about his great idea. Which of course he wouldn't tell anybody what it was. I told him that's crap, I will give you three ideas right now. I don't remember what they were, but I had them ready.
      I'd been considering creating a website where I would post new ideas, regularly. And I'd been wondering if I could do it at the rate of one per day.
      (If you do set up a website like this, there are a couple ideas you'll want to implement first, which I will helpfully provide here: Let people pay to see ideas in advance. Let people pay to keep ideas from being published.)
      Coming up with ideas is actually incredibly easy. Reality is extremely pliable if you look at it right. All the pieces you need are already right there, you just have to rearrange them a little.
      Seeing the new arrangement is the easy part. There's how things are, and then how things should be. It is the transformation that must be applied to reality to get from the first arrangement to the second which is the hard part.
      (In my stories, you'll see me refer to this as the cobain. Picture an extremely complex set of equations, software, functions, mappings, defining how to get from one reality to another. This is where the THINGs live. But I've found it a useful tool for thinking about the kinds of transformations I can actually apply to reality, too.)
      Anyway, to prove my point about the relative worth of ideas, here's some ideas about phones—
        iPhone app which samples input during Siri requests or audio portion of FaceTime etc, and outputs ultrasonic cancellation wave, dropping by 40dB spoken requests and conversations overheard by passers by.
        Silent Siri, an add-on that uses your iPhone or iPad's camera to read your lips
        Silent Siri Plus, uses 8 sensors and patented active cancellation to form an actual cone of silence
        Ultrasonic transducer arrays on surface of watch, using controlled interference to render subharmonics in human range audible only to the wearer. Targeting aided by camera mounted on the watch. This is how Dick Tracy's watch and the Star Trek communicator's actually function.
        Read My Lips—iPhone app that takes dictation via the front camera, by lip reading
        Face ID+, My face plus these facial gestures unlocks for transactions
      And here are some ideas about augmented reality and the wheel—
        voice announcing sustained speed changes
        voice providing color commentary
        app that announces jurisdiction changes via GPS and legal status for euc, max speed, etc
        voice talks you through learning to ride, advice prompts like training area in videogame, based on sensor data
        sound generator mixes recordings and adjusts for speed and turning, plays via speakers or bluetooth on phone
      Having an idea is great. It's like a pet you never have to clean up after.
  August 27
    I have wasted a lot of time not writing.
    Another Markdown test
      (1 min read)
      An excerpt from an upcoming series of posts, originally written on Twitter, February 2017. These were all written under the old 140 character limit, and I put a lot of time into formatting them as tweets. I actually care a huge amount about the white-space formatting in these jokes. (See this post for a lot more about this.)
      There's only one of this sort in the Biden series I posted earlier, and it's not formatted right. Hence the experiments.
      ---
      THIS FALL ON TRUMPTV
      **DEATH WARRANT NSC**
      *Real Drone Targets. Real Decisions.*
      Episode 2: Holy Shit Was That a Schoolbus?
      ---
      THIS FALL ON TRUMPTV
      **PRESIDENT'S BEST**
      **MILITARY FANTASIES**
      Episode 1: NUKING SHIT GOOD
      **TRUMPTV**
      *GRAB THE APOCALYPSE BY THE PUSSY*
      ---
      The original tweets for these two are here and here. You can see I've not quite got the line breaks right yet. And I forgot that the RSS feed just contains the raw Markdown, kind of. I guess if I bold and italicize using HTML instead of Markdown it shows up.
    Memories from another kurt, VI
      (1 min read)
      Every morning the milk truck came by our school. In a previous life it had been a cement truck. The drum still spun, but what came out the chute was milk. You tried real hard not to think about what was in that drum, but that just made it worse.
      After those kids pushed Lonny inside and then couldn't get him out, and they panicked, and left him in there for six hours, well, after that you couldn't help but imagine what it must have been like for him.
      Unable to keep his footing, he'd ended up just rolling on the bottom of the drum, letting the millions of scrabbling skittering limbs and antennae roll over in a never-ending standing wave of horror.
      When the people in hazmat suits finally pulled him out of there the bugs kept scrambling out of his clothes until just before the coroner arrived.
      Lonny had only been dead for a few minutes. He'd fought, and only lost right at the finish line.
      I drink my coffee black.
      I ~ II ~ III ~ IV ~ V ~ VI
    Someday I'll write more about Wirehose. It's defunct now. But twenty years ago, it was a developer framework for building things like scalable, branded, personalized, hyper-local news sites for TV stations and newspapers. The Hello World example for the developer docs, shown here, was basically an RSS aggregator, but some projects used the AP wire feeds, sports clips, various sorts of multimedia. I should probably do something about that website at some point.
    Here's some more of what happened during the first few days of the Biden administration, as live-blogged by me at the time.
    Day 5
      (2 min read • Illustration by DALL-E)
      ---
      Trump’s basic human empathy:
      Trump’s basic human empathy: …
      Trumps basic human empathy: um
      Trump’s basic human empathy: guys
      Trump’s basic human empathy: can i come out yet?
      Trump’s basic human empathy: it’s really dark in here
      Trump’s basic human empathy:
      ---
      Trump's basic human empathy: guys I know it’s been 74 years
      Trumps basic human empathy: which is the entire duration of human existence
      Trump’s basic human empathy: really a stupendous length of time
      Trumps basic human empathy: the longest
      Trumps basic human empathy:
      ---
      Trump’s basic human empathy:
      Trump‘s basic human empathy: guys
      Trump's basic human empathy: i know you heard me
      Trump's basic human empathy: i can hear you giggling
      Trump's basic human empathy: i told you before it’s really creepy when you make that noise
      ---
      Trump's basic human empathy:
      Trump's basic human empathy: guys
      Trump's basic human empathy: this is the coldest, darkest place that ever existed
      Trump’s basic human empathy: since the dawn of time 74 years ago
      Trump’s basic human empathy: you can’t even tweet it’s so cold
      ---
      Trump's basic human empathy:
      Trump's basic human empathy: guys
      Trump's basic human empathy: what if you were trapped here
      Trump's basic human empathy: how would that make you feel
      Trump's basic human empathy:
      Trump's basic human empathy:
      Trump's basic human empathy: oh fuck
      ---
      SECOND IMPEACHMENT
      Republicans: If he had succeeded we wouldn’t have to sit here in this chamber with you democrats
      Republicans: Besides we’re pretty sure he learned his lesson
      Trump’s shoulder devil 1 & 2: [in unison] Next time use MORE violence!
      ---
      Putin: OK, so you are at great, uh, personal risk of criminal prosecution in many—how many?
      Assistant: 37
      Putin: 37 jurisdictions. This is no problem. Did you wire the money?
      Trump: Did that not go through yet? FUCKING BANKERS!!
      Putin: Is not bank
      Trump: [slumps] No
      ---
      Trump: I don’t have $275 million handy
      Putin: Is only way, dear boy. Let me help you
      Putin: Is small price to keep golfing yes?
      Putin: The seminar is worth ten times everybody say
      Putin: You know who has taken seminar twice?
      Putin: Kim! He is seize the opportunity!
      ---
      Putin: This seminar taught by me personally. Is only place in world to learn true secrets of extradition. Is not hard, just say yes
      Putin: If acting now, for low price i include bonus. You like bonus. You get CD with audiobook, I read, very nice
      Putin: OK, so $345 million
      ---
      Trump: I’ll do it!
      Putin: You will not regret this my dear boy
      Trump: You’ll have the money in 2 weeks
      Putin: No i will get the money TODAY because you are a LOSER and you want to be a WINNER. You know who is winner?
      Trump: Kim?
      Putin: Yes. He is making laughs at you
      ---
      Trump: It is so unfair
      Putin: Is simple. Kim is winner, you are loser
      Trump: I am SO a winner!!
      Putin: How many nuclear weapons do you have?
      Trump: …
      Putin: And how many Kim has?
      Trump: …
      Putin: Yes? You see? is simple. Trump? LOSER
      Putin: You need my new seminar
      ---
      Day 2 ~ Day 3 ~ Day 4 ~ Day 5 ~ Day 6 ~ Day 7 ~ Day 8 ~ Day 9
    The Book of Trump 1:16–18
      (Illustration by DALL-E)
      16 His absolutely perfect rages thus well vented, on the sixth day He golfed. 17 And the fucking ball did go into the rough and so again His wrath arose 18 and the suckers again were frightened. They sent an offering of manly men to call Him “Sir” and
      ---
      Day 2 ~ Day 3 ~ Day 4 ~ Day 5 ~ Day 6 ~ Day 7 ~ Day 8 ~ Day 9
    Day 7
      (2 min read • Illustration by DALL-E)
      ---
      Trump: Who’s greater, me or Lincoln?
      Putin: Is no contest, Lincoln
      Trump: FUCK LINCOLN WHATS HE GOT
      Putin: He has 620,000 dead citizen in civil war
      Putin: You have only 400,000 and no war
      Putin: But hey better luck next time, eh?
      ---
      Trump: I AM SO FUCKING HUNGRY!!
      Trump: YOU!! WHY AM I NOT EATING RIGHT NOW?!!
      Intern: um McDonalds closed your tab
      Trump: [turns] YOU!!! WHY ARE WE NOT COOKING THAT INTERN RIGHT NOW?!!
      ---
      Constituent: So why object to metal detectors? Is it so you can bring a gun to your workplace?
      Representative Guncuddler: Yes. I want to have a loaded gun with me when I have frank discussions with my colleagues. I thought that would be obvious.
      Constituent: …
      ---
      Constituent: Still trying to figure out the whole “need a gun at the office” thing
      Representative Guncuddler: Well, I might get to murder one or more of my coworkers
      Constituent: Did you just
      Representative Guncuddler: I meant HAVE to murder one or more of my coworkers
      ---
      Representative Guncuddler: And I stand here today ready to kill anyone that disagrees with my right to carry this beautiful device that lets me kill anyone I see
      Representative Guncuddler: Some say preventing random impulsive murder is good. I say, let’s have that debate!
      ---
      Representative Guncuddler: If we prevent the godgiven right of anyone with white skin to randomly flip out and murder those around them, then all our murders will be PREMEDITATED and my constituents are against premeditated murder
      Constituent: Except democrats!
      ---
      Intern 1: [whispering] What’s he doing?
      Intern 2: Literally holding his breath until he turns blue
      Intern 1: Still can’t get past that throbbing purple color
      Intern 2: Nope
      ---
      Senator: I disagree with my esteemed colleagues on the necessity of being able to murder those around you at any moment
      Senator: I prefer to be part of a rioting mob
      Senator: That’s the way my grandfather terrorized and murdered his neighbors and it’s good enough for me
      ---
      Trump: If I kill someone on 5th Ave i wont lose any followers…
      Trump: Social media took all my followers…
      Trump: [thinking really hard]
      Trump: …
      Trump: YOU!! GET MY GUN, WE'RE GOING TO THE CITY!
      ---
      Ivanka: I am SO MAD at daddy
      Ivanka: I was going to be president in 2024 and now he’s not president and he can’t even pardon anymore and I just… everything is RUINED
      Jared: Maybe he’s worried you can do better than 400,000
      Ivanka: Don’t say that!! he did his best!
      ---
      Intern 1: Why are we removing all the mirrors? Is he really a vampire?
      Intern 2: No, he just keeps losing arguments whenever he sees one
      Trump: FUCK YOU, I'M NOT PAYING
      Mirror Trump: FUCK YOU I'M NOT PAYING
      Trump: This guy is good
      ---
      Trump: I WILL EAT YOUR HEART FOR BREAKFAST!
      Mirror Trump: I WILL EAT YOUR HEART FOR BREAKFAST!! ALSO HAVE YOU BEEN WORKING OUT? YOU LOOK GREAT
      Trump: Hahaha FUCK YOU
      Trumps: [unison] LETS GO GRAB SOME PUSSY!!
      ---
      Putin: I have an amazing opportunity for you my dear boy
      Putin: I can get you your Nobel prize
      Putin: I have guy on the board, he owes me favor
      Putin: He just needs small amount money for expenses
      Trump: Expenses?
      Putin: “Expenses”
      Trump: Ohhhh
      Putin: $25 million
      ---
      Day 2 ~ Day 3 ~ Day 4 ~ Day 5 ~ Day 6 ~ Day 7 ~ Day 8 ~ Day 9
    Day 8
      (4 min read • Illustration by DALL-E)
      ---
      Intern 1: Shit
      Intern 2: ?
      Intern 1: He can’t find his ivory and rhino horn backscratcher
      Intern 2: Shit. Flip for it?
      Intern 1: I guess it’s my turn since I’m the one that hid it
      ---
      Trump: WHERE THE FUCKING HELL IS MY FUCKING BACKSCRATCHER!!!!??
      Intern: Well sir—
      Trump: I AM RIGHT IN THE MIDDLE OF YELLING DO NOT EVER FUCKING INTERRUPT ME WHEN I AM STILL YELLING DO YOU FUCKING UNDERSTAND??!!! [pause]
      Intern: Yes?
      Trump: I AM STILL FUCKING YELLING!
      ---
      Trump: AND FURTHERMORE THE EXACT REASON I HAVE BEEN YELLING FOR THE PAST HOUR IS
      Trump: THE REASON IS
      Trump: um
      Trump: YOU! Why was I yelling at you?!
      ---
      Trump: The democrats stole my backscratcher!!
      Trump: This is a problem that can only be solved by violence. A very special beautiful kind of violence
      Trump: The kind where I say stuff and other people get violent!
      Trump: Nobody gets hurt!
      Intern: …
      Trump: Yup nobody
      ---
      Trump: What do you mean I can get in trouble for things other people do just because I told them to do it
      “Lawyer”: Well there are a lot of statutes that—
      Trump: I SWEAR TO TRUMP I WILL NOT REST UNTIL EVERY STATUE IS CRUSHED INTO RUBBLE!!
      ---
      Trump: I never told the suckers to attack congress!
      “Lawyer”: You don’t need to say the exact words
      Trump: Are you fucking kidding me? How can it be words?
      “Lawyer”: …
      Trump: Words are just sounds I make with my mouth
      Trump: Like farting!
      ---
      Trump: And as part of my announcement that I will be the next president of the United States, I will be introducing a new line of financial instruments, and I think you’re going to love them
      Trump: We are going to remake justice and finance and who knows I may wet my beak
      ---
      Trump: As your next president my treasury department will be issuing a new series of CLEMENCY BONDS, I call them pardon bonds
      Trump: Buy them now at a discount and redeem them for FULL CREDIT toward a presidential pardon
      Trump: It’s really a no brainer folks
      ---
      Trump: In addition to being the best, most amazing way to invest in your future, we are going to put all the pardon bonds, from all across America, we’re going to put them into a market, and that market, that derivatives-based futures market will make us all so wealthy
      ---
      Trump: As your next president I will be giving CASH DISCOUNTS for FAST PARDONS
      Trump: Did you steal from the poor to get rich? Sounds like you may need a pardon!
      Trump: I don’t give a shit where you stole the money from, just cut me in and you’ll be HOME FREE
      ---
      TRUMP BRAND PARDONS
      FAMOUS EVERYWHERE
      YOU STOLE IT, NOW ENJOY IT
      DISCOUNT FOR CASH
      LOW LOW FINANCING
      ---
      Trump: What do you mean I can’t have more of that stuff they gave me at the hospital?!!
      Doctor: It’s quite expensive and we must ensure it goes to those most in need
      Trump: That’s bullshit!! I got that shit in my veins every 72 FUCKING HOURS when I was king AND I NEED IT
      ---
      Trump: When I was king of America I got respect from around the world!!
      Trump: I could have beheaded peasants and then rolled their heads down that staircase thing they have at Times Square
      Trump: Bounce bounce bounce
      Trump: Why didn’t I do that when I had the chance?
      ---
      Intern 1: He’s going through a lot of sharpies, what’s it this time?
      Intern 2: “Those who will be made to eat dog shit first”
      Intern 1: Is that part of his series on who gets beheaded when he resumes his rightful place on the throne of America?
      Intern 2: Part 83
      ---
      Trump: AINT NO PARTY LIKE A PATRIOT PARTY
      Trump: GET UP AND DANCE WITH ME
      Intern 1: Is he…
      Intern 2: Twerking. Yes. Yes he is
      Trump: IT AINT TREASON IF YOU WIN AND ALSO ARE THE KING
      Interns: [unison] I can never unsee that
      Trump: BREAK IT DOWN!!
      ---
      Intern 1: Why is he making a music video? Who thought this was a good idea?
      Intern 2: And why is it the tune of Achy Breaky Heart?
      Chief legal strategist and top advisor and also good at crimes guy Rudy: Fuck if I know I was so fucking high that day TRUMP BRAND CRANK YO!
      ---
      Rudy: OH MAN I AM SO FUCKING HIGH RIGHT NOW
      Putin: Hello yes we establish that twenty minutes ago
      Rudy: WOOOOOOO YAAAAAAA
      Rudy: Just a sec
      Putin: Are you hitting drug pipe again?
      Rudy: OHHHH FUUCCCKK NOOOOOO MAN
      Putin: I can hear your lighter
      ---
      Trump: OK let’s hear this new slogan
      Intern 1: FUCK YOUR STUPID LAWS AND MAKE ME KING
      Trump: It sucks!!
      Trump: Got it
      Trump: FUCK YOUR STUPID LAWS AND MAKE ME KING AGAIN
      Intern 2: Does he even know what a president is?
      ---
      Trump: We are going to need 32 million hats embroidered with “FUCK YOUR STUPID LAWS AND MAKE ME KING AGAIN”
      Trump: I want them made in the cruelest fashion possible
      Trump: They still have baby seals right?
      ---
      Trump: OK folks this is an emergency
      Trump: Rudy lost the entire “election investigation fund”
      Team of Idiots: [giggle]
      Trump: He lost the ENTIRE FUND!!
      Trump: How did this happen Rudy?
      Rudy: It went into the vortex?
      Trump: THATS RIGHT IT WENT IN THE FUCKING VORTEX!!!
      ---
      Trump: What did I say about the vortex?
      Rudy: To worship it?
      Trump: And…?
      Rudy: [mumbles]
      Trump: I can’t hear you asshole
      Rudy: To not fuck with it
      Trump: DO. NOT. FUCK. WITH. THE. VORTEX!!!!
      Trump: [twitches]
      Intern: Shh, I think he’s having the vortex dream
      ---
      Trump: Before, I was a king
      Trump: But with the power of this vortex, I shall become SUPER-KING!
      VORTEX: You sure that’s what you want to go with?
      ---
      Intern 1: I wonder why he keeps having that vortex dream
      Intern 2: Maybe it’s that vortex down the hall
      Intern 1: That’s probably it
      ---
      Day 2 ~ Day 3 ~ Day 4 ~ Day 5 ~ Day 6 ~ Day 7 ~ Day 8 ~ Day 9
    Day 9
      (1 min read • Illustration by DALL-E)
      ---
      Trump: Finally one of you stupid doctors can get it right!
      “Doctor”: OK this is going to pinch a little
      Trump: This is the stuff they gave me at the royal hospital right?
      “Doctor”: It’s even MORE experimental
      Trump: How experimental?
      “Doctor”: I made it myself!
      ---
      Trump: How long does it take to kick in doc?
      “Doctor”: Not long, about now actually
      Trump: Ohhhh yeahhh
      Trump: Good job doc, I won’t have you beheaded this week
      “Doctor”: Just let me know when you need a bump
      ---
      Trump: Hey doc I think I need another treatment
      “Doctor”: OK! let me get it ready
      Trump: What’s in this stuff anyway?
      “Doctor”: I made it myself from kangaroo sweat!
      Trump: As long as that is an aryan kangaroo I’m good
      ---
      Intern 1: He’s just kind of laying there
      Intern 2: But he’s breathing right?
      Intern 1: Oh sure, you can tell he’s totally fine
      Trump: MY FAVORITE WAY TO EAT A SMURF IS FRESH CAUGHT RAW AND WIGGLY
      Interns: Totally fine
      ---
      Trump: STOMP STOMP WATCH ME STOMP
      Intern 1: Do you think we should call that doctor back?
      Trump: SMURFS GO SMOOSH!! SMURFS GO SMOOOOSH!!!
      Intern 2: It’ll wear off eventually. Besides those little blue fuckers have been a real problem lately
      Intern 1: This is true
      ---
      Trump: JUICY AND CRUNCHY
      Trump: BLUE AND WIGGLY
      Intern 1: I have never seen pupils that big
      Intern 2: Totally fine
      Trump: EENSY WEENSY TASTY TREATS!!
      ---
      Trump: Oh god I feel terrible
      Trump: And I dreamt I was a kangaroo
      Trump: Did I
      Trump: Did I eat smurfs?!
      Trump: …
      Trump: Those little fuckers
      ---
      Day 2 ~ Day 3 ~ Day 4 ~ Day 5 ~ Day 6 ~ Day 7 ~ Day 8 ~ Day 9
  August 26
    When nobody believes in you, that's when you have to believe in yourself. HAHAHAHAHAHAHAHAHA kidding. If nobody believes in you, it's probably for a good reason, asshole.
    Memories from another kurt, V
      (1 min read)
      I am mostly a trader of ideas. I can move goods. But the goods are so astronomically expensive to transport nobody does it. If you ever see actual cargo come across the cobain, you know something apocalyptic is about to happen. Nobody does it that way.
      Information attacks are where it's at. And this kind of war goes on all the time and nobody here has any idea it's going on.
      For example, crypto is an information attack from another kurt. It operates similar to religion. It exploits several loopholes in human psychology, and propagates itself. By nature it is designed to squander resources, enable only instability and speculation, and erode trust in society and institutions such as organized government.
      Now let me tell you about this amazing drug delivery device your kurt is going to absolutely love.
      I ~ II ~ III ~ IV ~ V ~ VI
    Day 2
      I live-blogged the first days of the Biden administration on Twitter. I'm reposting it here because it makes me laugh, and it's OK to laugh at your own jokes, probably. The whole thing is about a ten minute read.
      (1 min read • Illustration by DALL-E)
      ---
      Joe Biden steps out onto the east lawn, bathrobe, cell phone and a crack pipe. His plan to gain the most Twitter followers in history is in motion.
      ---
      Mr Trump demands a very large sea turtle and when it arrives later that day, he insists it be his caddy “or suffer the consequences”. He fires the turtle on the 5th hole and vows to make soup before he pays that fucking turtle
      ---
      Jared and Ivanka drop their bags and kick the door closed, “oh. my. god... it feels sooooo GOOD to RELAX!!” and uncurl their tails
      ---
      entire nation, yes including EVERYONE I MEAN YOU DON’T LIE, relaxes that thing we’ve all had clenched, even if only for like an hour
      ---
      SEDITION GUY 1: I don’t get it how did the government find us, those guys are incompetent
      SEDITION GUY 2: dude maybe we should be ninjas that would be amazing
      SEDITION GUY 1: yeah those guys are invisible
      SEDITION GUY 2: ninjas can still livestream EVEN INVISIBLE
      ---
      Days 2–ongoing
      Trump references nuking something in an otherwise unrelated conversation between 16 and 85 times per day
      ---
      four hundred fucking thousand people still fucking dead for one man’s fucking dysfunction
      ---
      Day 2 ~ Day 3 ~ Day 4 ~ Day 5 ~ Day 6 ~ Day 7 ~ Day 8 ~ Day 9
    Day 3
      (2 min read • Illustration by DALL-E)
      ---
      Trump approves bid from contractor suckers to begin work on 5,000-foot-high monument of his middle finger which is perfectly sized
      ---
      Trump fires the leopard
      ---
      Q Idiot 1: i don’t get it, did they not see the proof?! there were baby bottles of bubbly blood in the supermarkets
      Q Idiot 2: I know right, it was in every single grocery store in the country
      Q Idiot 1: They tried to trick me by keeping it out of mine
      Q Idiot 2: Me too
      ---
      THING A: [hoovering sound, blaze of lights, gravity fluctuations]
      THING A: ... !!!
      THING A: HOLY FUCK
      THING B: That’s pure 2020 right there
      THING A: No wonder that universe is banned
      THING A: [horfles another line, 3 galaxies spin faster]
      THING A: This shit is tight
      ---
      Day of the Fuckheads
      Sedition Guy 1: Dude we better hide these weapons before we go inside to look for people to kidnap and murder
      Sedition Guy 2: We should livestream this so we know where we hid them
      Sedition Guy 1: Oh good call
      Sedition Guy 2: It’s what i trained for
      ---
      Completely real in every way patriotic trembling overcome with emotion really for the first time ever tears real tears streaming down his patriotic features: Sir, i know the constitution because i studied it and it says right there you should be king
      Trump: I love naptime
      ---
      Trump’s shoulder devil: So the lesson learned HAHAHAHA
      Trump’s shoulder angel KIDDING it’s another shoulder devil: I will never get tired of that, seriously
      Trump’s shoulder devil 1: I fucking love this job
      Trump’s shoulder devil 2: Let’s make him froth at the mouth
      ---
      Trump lawyer 1: Wasn’t there a thing where like if you and other people commit like a felony and someone like dies there’s like a thing they can get you on even if you just told other people to do a thing?
      Lawyer 2: Doesn't ring a bell
      Lawyer 1: Phew let's get high again
      ---
      Trump intern 1: Why does he need a list of his golf courses sorted by extradition status?
      Intern 2: You’d think he'd have that list memorized
      Intern 2: You ok
      Intern 1: Yeah lost my breath laughing. Do it again
      Intern 1: "Memorized"
      Intern 2: “Are we getting paid”
      ---
      Trump aide 1: Do you have the price list handy?
      Aide 2: Pardons?
      Aide 1: No, the other one
      Aide 2: Commutations?
      Aide 1: Nope
      Aide 2: Aid and comfort?
      Aide 1: That’s the one
      Aide 2: What’s he need it for
      Aide 1: Some new kind of “super treason”
      ---
      Day 2 ~ Day 3 ~ Day 4 ~ Day 5 ~ Day 6 ~ Day 7 ~ Day 8 ~ Day 9
    Day 4
      (2 min read • Illustration by DALL-E)
      ---
      Trump: THEY CAN’T FUCKING STOP TRUMP FROM BEING PRESIDENT AGAIN
      Aide 1: Actually, they can
      Rudy: It’s ok I have a plan
      Rudy: The constitution says if your roommate dies or you lose the vote you can give yourself an EVEN BETTER JOB
      Rudy: Putin knows his shit
      ---
      Putin on speakerphone: Yes, is so good once again to talk to you without all those secure phones
      Trump: I came up with my new job title you will never guess in a million years guess come on guess GUESS GUESS!!!!!
      Putin: Is it “Super President”?
      Trump: ARE YOU A WITCH?!!
      ---
      Trump: How did you know about Super President?
      Putin: I tell you last time, is not good because you need cape
      Trump: (slumping, small voice) You really don’t like it?
      Putin: It’s ok. Maybe great world leader is not for you
      Putin: Did you ever launder that $150M for me?
      ---
      Friend 1: Hey it’s been so long guys, come on upstairs, my house is your house
      Insurrectionist 1: OUR HOUSE!!!
      Insurrectionist 2: OUR HOUSE MOTHERFUCKERS HOW YOU LIKE US NOW!!
      [shattering and crashing noises]
      friend 1: Oh right
      ---
      Trump: MISTER Super President
      Putin: No
      Trump: The greatest!
      Putin: Is already boxer
      Trump: VELOCIRAPTOR-IN-CHIEF!!
      Putin: No dinosaur except T-Rex, you know why
      Trump: It’s my stubby little fingers
      Putin: Yes it is
      Trump: HERO OF THE RUSSIAN FEDERATION!
      Putin: …
      ---
      Friend 1: Besides freedom, why do you guys bring guns to protests
      Guncuddler 1: In case i need to murder someone, duh
      Guncuddler 2: Yup never know when someone gonna need murdering
      Friend 1: And the assault rifle?
      Guncuddler 1: Sometimes a LOT of people need murdering
      ---
      Trump: I have my new job title and it’s WAY BETTER than president which sounds stupid anyway!!
      Putin: ok
      Trump: It’s genius because i stand by my CONVICTIONS and I am the best at FREE TRADE
      Putin: I am chills
      Trump: CONVICTED TRADER
      Putin: You are so, so special to me
      ---
      FIRST IMPEACHMENT
      Republicans: Breaking the law to stay in power is ok
      Republicans: Besides we’re pretty sure he learned his lesson
      Trump’s shoulder devil 1: Next time use violence
      Devil 2: You think violence solves everything
      Devil 1: Well, it does
      Devil 2: Good point
      ---
      Day 2 ~ Day 3 ~ Day 4 ~ Day 5 ~ Day 6 ~ Day 7 ~ Day 8 ~ Day 9
  August 25
    Here's a little piece I like to call "information flow in a world of teamwork." I hope it is obvious I have not yet tried DALL-E.
    A less exhausting guide to podcasting in 2022 – A Whole Lotta Nothing
    Got access to DALL-E 2. Of course the first thing I did was click straight through to the legal stuff.
  August 24
    I added art to another of my favorite pieces, one I re-read regularly.
    Memories from another kurt, IV
      (1 min read)
      If you were one of the few hundred million people living at the top of the economic and social ladder in the twentieth and twenty-first centuries on Earth, you had a better lifestyle than any great ruler in the human history that preceded you.
      And because much of the wealth and power was concentrated in a people whose most common societal emotion was fear, and specifically fear of retaliation, of revenge, of the other coming back to take what was stolen, you comforted yourself with fictional dystopias where one or more parameters on reality got tweaked. And the fun was seeing just how bad it could get.
      I envy those fucking clowns.
      I ~ II ~ III ~ IV ~ V ~ VI
    Memories from another kurt, III
      (1 min read)
      The sound of an industrial scale tribble slaughterhouse will drill into your soul like radioactive steel tinnitus made of car alarms made from serrated knives dipped in salt. There is no hearing protection available that can muffle this sound. It operates directly on the nervous system, via the same mechanism that gives the tribble its unique ability to calm us.
      Humans cannot work under those conditions. Large scale tribble farming didn't become a thing until advances in AI and robotics enabled fully automated tribble factories.
      The thing is, the tribbles still need to be cuddled, right up to the end.
      Stretched out before you, in a vast warehouse with high ceilings, what appear to be an endless series of Ikea-type ballpits, filled with a riot of fuzzy balls. And little kids, playing happily in pit after pit, giggling and laughing like they're on a playground in a TV commercial.
      They scoop, scoop, scoop! And carry, carry, carry!
      And so deftly, snick! snick! snick! with the knife!
      The little fingers carefully hold the fur aside, and pluck! pluck! pluck! the delicious parts out, and put them on the tray.
      Then they return to the ballpit for another basket.
      They don't look exactly like little kids, when you look at one up close. But they have to be similar enough to human kids, in how they look, and how they play. This is how tribbles are, they need that.
      And that's the story I was told. It's the same one we've all heard.
      But the truth is so, so much worse than you think.
      I ~ II ~ III ~ IV ~ V ~ VI
    When everything is hot garbage, that’s when it’s time to slaughter some tribbles.
  August 23
    Drummer has corrupted another file.
    How to use Roady to recover a corrupted Drummer file
      First, determine that the file is actually corrupted. This is pretty easy, the file will appear to be empty, and Drummer's tab controls will start acting weird.
      Tools → Reset tabs… is the first thing you should try. This will close all your tabs, and you'll start back up with just one tab for your Notes file.
      Then, try the file again with File → Open…, and see what you get. If it's still empty, and you know it shouldn't be, it's time to check your backups.
      Sign in to GitHub and go to the page for your private Drummer backups repository.
      Then, find the file that you need to restore. If it's a public file, it'll be in the publicFiles folder, otherwise it's in privateFiles.
      Use the History button to view older versions. Clicking on the snarky saying for a version will show you the differences between that version and the one that came before it. On the right-hand side, there's an icon that looks like a sheet of paper with some angle brackets. This will show you the full contents of that version.
      Once you've found the version you want to restore, use the Raw button to get the plain contents of the file. Save that file somewhere.
      Now switch back to Drummer, and the tab for the file you want to restore. You may want to reset tabs again, and then re-open the tab.
      Use File → Import local file… to restore the contents of the file. You may need to close the tab and re-open it to see the results of the import.
      Use File → Edit OPML headers… to restore the title and any other custom headers.
  August 22
    I'm interested in AI mostly because I have no talent, but lots of ideas.
    Memories from another kurt, II
      (1 min read)
      OK, first we nationalize all the billionaires, she says.
      What? What the fuck are you talking about. You can't do that.
      This thing lets us dial up fucking universes of possibility, right? Well, I want to see what happens when you nationalize all the billionaires.
      There is no way anybody has ever or would ever just up and nationalize all the billionaires. There's no point in looking.
      Who said anything about looking?
      Pause. You are fucking crazy.
      That look in her eyes. God I love that look.
      I ~ II ~ III ~ IV ~ V ~ VI
    Memories from another kurt
      (1 min read)
      Weirdest thing I ever felt was dental clay. Stick a block of this stuff in your mouth, bite down hard. In the next five minutes it does a year's worth of repair and maintenance on your teeth. The surface becomes foamy and it fills every single space it can, between your teeth and under your tongue and way back behind your back teeth, way back where it sets you gagging just thinking about it, everywhere. You can still breathe and what's really crazy you can actually talk once you get used to having a billion tiny half biological machines insinuating themselves right into your very gums. Because fuck you you have gum disease and you don't know it. That's what my mama always said anyway.
      I ~ II ~ III ~ IV ~ V ~ VI
  August 21
    Drummer has again corrupted a file, which I have again had to recover using Roady. It may be this bug, which has been reported, with a fix identified, more than once.
    How to find opportunities
      (1 min read)
      I've run companies, given seminars on ideas, done a lot of business process consulting. Finding opportunities can be approached systematically:
      Where do money and product change hands, and how can we disrupt and extract money
      Increase engagement, and then use that engagement to sell things
      Drop barriers to giving us money
      Reward the engaged/thought leaders
      Help the community build things of value
      What disparate things ought to be integrated
      What do we have that others don't
      If you've watched that Beatles documentary on the making of Let it Be, you've seen how musical opportunities naturally arise, and get included and refined. They were looking for places to include drama, and emotion, and rhythm, and were able to build these experiences for us in an intuitive, fluid process. Their vocabulary was honed by years of constant writing and playing.
      What's the vocabulary for your business?
    If you’re ever looking for great ideas that nobody has time for, I’m your guy.
    Preliminary research results from 325 hours of Dinosaur Train
      (1 min read)
      One of the best parts about having a kid is getting to revisit topics you loved when you were a kid, like dinosaurs. Paleontologists make new discoveries all the time. For example, apparently there's no such thing as a pterodactyl, and plesiosaurs like the Loch Ness monster aren't actually dinosaurs at all!
      Before I started watching Dinosaur Train, I didn't know much about troodons. Just that being corvids and tool users, they hunted in packs armed with spears. But it turns out, history is so much more fascinating than I'd thought:
      At its peak the Troodon empire claimed the Triassic, Jurassic and Cretaceous through time tunnel technology.
      The Troodon Empire was known to practice forced adoption of unrelated species as political enforcers.
      The secret police of the Troodon Empire was known as The Claw, and Conductor is among its highest ranks.
      The state religion of the Troodon Empire included rites worshipping at a volcano known as Ol' Smoky.
      Pteranodon slaves dropped dinosaurs from throughout Mesozoic into Ol' Smoky to propitiate those who built the time tunnels.
      Some pteranadons served willingly, a secret held from their own families, ambassadors to eras with common fear of troodons.
      Those cultures most fully under the thumb of the Troodon Empire often practiced a form of rishathra peculiar to dinosaurs.
  August 20
    Apparently I write about a lot of different things here. I tried to arrange them into categories and they all kind of overlap. Anyway, I put the funny stuff first.
    I finally got a stylesheet for Drummer that fixes most of the problems I've had on the laptop, and then I tested it on the iPad. Yikes. Safari has a "responsive design mode" on macOS, but it lies. To enable actual responsive design mode on the iPad, I need to connect it to a real computer with actual wires. I will get around to that, but will also note that according to Apple, this laptop should be able to run iPad apps all by itself.

    Your next grift
    Don't miss out!! Here are some great crypto grifts to choose from.

      (5 min read)
      Crypto is the grift that can never be stopped because it is parasitic greed in the purest possible form, and greed is the thing that brings the mark and the grifter together in such sweet harmony.
      Don’t miss out!!
      Here is an assortment of grifts to choose from:
      ---
      My next grift will be convincing local school districts to put academic records on a blockchain, and then selling NFTs to parents for school pictures and report cards.
      ---
      My next grift will be selling people NFTs of their tweets, and then encouraging them to sue when retweeted
      ---
      My next grift is a dating app that lets you buy and sell NFTs that represent one-hour blocks of “date time”
      Working title: Nonfungible, Indeed
      ---
      My next grift will be advising billionaires how to steal assets “controlled” by blockchains the old-fashioned way: the legal system
      ---
      My next grift will be NFT Superstar, where your entries are NFTs, and the votes are on a blockchain
      ---
      My next grift is Monopoly except with NFTs so you can literally own Boardwalk
      ---
      My next grift is going to be portable electric heaters that are really just crypto miners
      ---
      My next grift will be NFT boons for organized play. Also, all your sessions are now on the blockchain, because my cousin needed a gig
      ---
      My next grift will be NFT dice for your VTT
      ---
      My next grift will be selling individual Pokémon as NFT. Why shouldn’t a billionaire own Pikachu or Snorlax? It’s only fair
      ---
      My next grift will be selling NFTs of the historic documents I took home after I got let go from my last job
      ---
      My next grift will be a low-power mesh of water meters that record each flush on the local around the block chain.
      ---
      My next grift will involve convincing people to pay for NFTs of QR codes.
      ---
      My next grift is Ticketmaster, except now every ticket is an NFT. (Also there is only bidding.)
      ---
      My next grift will be getting people to pay to have me prepare an NFT of their family recipes before it’s too late
      ---
      My next grift is a printer-scanner that issues an NFT and a handy QR code for everything
      ---
      My next grift will be that the only way to protect yourself is to make sure that literally everything you post needs to be an NFT, or else everyone will steal your ideas and Photoshop your face and steal your identity
      ---
      My next grift will be health insurers adding a per-scan NFT “health assurance” fee for your medical records, which enables a separate fee for storing and retrieving those records
      Also, if your thumb drive dies, you lost all your NFT records. Hehe the cruelty part is just for fun
      ---
      My next grift is going to be a series of NFTs which represent the carbon, heat and climate destruction caused to mint each one.
      The Blockchain of Shame will track the waste caused by each transfer of ownership.
      The value of each NFT will be directly tied to its ongoing impact.
      ---
      My next grift is Moviepass, except your tickets are MFTs (mask-free tokens) which are tracked via NFTs.
      This grift has a shorter lifespan than most because the marks will insist on dying.
      But they’ll still be terrified, and their need to do something, anything, will be my hook.
      ---
      My next grift will be a website where you enter your credit card info and it tells you that you bought an NFT
      ---
      My next grift is the +1
      Any digital data is just one extremely long number in computer language. If you just plus one to that number, you get a new number. And that is legally a whole new thing you can own!
      Just use my +1 app to purchase the digital copyright, or “NFT”
      ---
      My next grift is YOUR PET AS AN NFT
      Keep the memories alive forever
      ---
      My next grift is an app that keeps tigers away
      ---
      My next grift will be claiming that most clothing has invisible embedded QR codes that can uniquely identify the wearer in crowd photography or surveillance video; that law enforcement has scanners to read these unique IDs; and then selling protection against this.
      Prob an app.
      ---
      My next grift is going to be selling NFTs to sovereign citizens
      ---
      My next grift will be that if you use this app to take a picture of your drivers license, you will create an NFT, and it is that NFT which will have to appear in court, not you
      Of course we will just use your info for identity theft, duh.
      This is still an honest grift, even if it does use NFTs
      ---
      My next grift is, do you own the NFT for the Washington Post or New York Times home page for the time and date of your baby’s birth?
      Your grandchildren are going to CURSE you on Future Antiques Roadshow. You will be a meme. Not a good one.
      ---
      My next grift will be that you can upload any copyrighted material to the internet you like, as long as you declare that you are issuing an NFT for it, so it’s OK.
      Also? You get to SUE EVERYONE. I will make this happen for you. I just need some CYBER COINS to cover court fees.
      ---
      My next grift will be that bible codes and gematria are god’s word in NFT form, and you can profit from this because this is how god works
      ---
      My next grift is that you can get an NFT for the tracks you rip from vinyl, because they are unique to your turntable.
      So you can upload them to file sharing. And then sue people for downloading YOUR music
      ---
      My next grift is going to be even better than crypto.
      It is CYBER CRYPTO
      You won’t believe how much safer your money will be when it is cyber!!
      NOTHING is more valuable than a CYBER NFT!!
      ---
      My next grift will be, how can you prove your character sheet is accurate without blockchain? You cannot, you must NFT
      ---
      My next grift is Wordle, except when you win, you OWN that word, because it is an NFT.
      Feel free to sue everyone for using it!
      ---
      My next grift will be a card game where the cards are NFTs, but when you win, you get to destroy some of their NFTs, instantly, permanently, irrevocably. Or they can pay you.
      ---
      My next grift will be issuing NFTs for each hexagram of the I Ching
      ---
      My next grift will be a poetry competition that also issues an official NFT of your entry, for a small additional fee
      ---
      My next grift will be that you should own your DNA, for the good of your family, and you can do this through a simple thing called an NFT
      ---
      My next grift will be to convince evangelicals that crypto and NFTs are literally from Satan, and should be eradicated from the earth.
      I don’t actually have a grift for this one, I’ll do it for free
      KIDDING!!!
      Everybody knows when it comes to grifting, evangelicals are the sweetest plum
      ---
      My next grift will be an app that lets incels generate NFTs that represent the women that won’t have sex with them, and trade them in a free and open marketplace, to do with as they please
      ---
      My next grift will be getting small investors together with this fantastic opportunity to turn chess positions from historic games into NFTs. No, seriously, there’s a huge market for this, you cannot lose. Chess is huge now.
      ---
      My next grift will be Selfenefty, the app that turns your selfies into NFTs
      ---
      My next grift is custom, personalized blockchain cryptocurrencies for sovereign citizens. “I only recognize debts in Doug!tm!Coin”
      ---
      My next grift will be giving a TED Talk about how to be absolutely positive you are the one doing the grifting, and how that brings us all together
      ---
  August 16
    I can never type fast enough to keep up with what’s going on in here
  August 15

    The Way of the Barnacle
    Attend every meeting. Send all the emails. You are a barnacle. Even the stupidest person you know can apply this and advance to the top.

      (4 min read)
      ### The Barnacle of Power
      Attend every meeting. Send all the emails. Know nothing.
      You are a barnacle. Just insert yourself into the process, over and over. Take credit in little slices. They will all add up.
      Even the stupidest person you know can apply this and advance to the top
      ---
      ### The Barnacle of Wisdom
      When a barnacle rises high enough, they become all-knowing. For they have seen, and taken credit for, many decisions.
      The barnacle knows about every endeavor, and can ask important, insightful, intelligent, relevant questions about any topic at hand.
      ---
      ### The Barnacle of Genius
      At a certain point, the barnacle gains the power to imagine, and specify, in extremely clearly defined terms, literally any project open to humankind.
      The barnacle can simply will these things into being, through the power of amazing decisions.
      ---
      ### The Barnacle of Recall
      Key to maintaining your firm grip on the coattails of power, is your ability to draw from literally every fact in the world.
      And if you can pronounce a word, then you know literally every single thing one could possibly know about that subject. Use words!
      ---
      ### The Barnacle of All Domains
      Everything is in your wheelhouse. Any endeavor undertaken by your organization is relevant to what you are doing.
      You do not ask, you simply do. If there is the smallest fraction of plausibility why this territory is yours, take it.
      ---
      ### The Barnacle of Complete Deniability
      There is no possible way you are responsible for anything that goes wrong. Because you do not do anything. You are totally safe.
      All you do is decide what others should have done correctly.
      Everyone else is to blame.
      ---
      ### The Barnacle of Change
      When someone suggests anything you do not yet understand—perhaps because they haven’t yet finished their sentence—you can always, always, provide extremely valuable input by asking, “Are we sure this is a good idea?
      People need to hear this from you.
      ---
      ### The Barnacle of Tongues
      Eventually the barnacle’s ability to communicate clearly reach superhuman levels. The rules of grammar, spelling, sentences, commas, adjectives, pronouns, the shift key, and those dot things, with the little tails, yes permeation, the rules of permeation
      ---
      ### The Barnacle of Persistence
      Never, ever agree to a final decision on anything. This is vital. It can always be discussed more at a future meeting. Which you will have your assistant set up.
      Of course you get assistants. Not just one, either.
      One is a threat to your power.
      ---
      ### The Barnacle of Accretion
      If you have one assistant, they will be doing all your work.
      They can replace you.
      If you have two assistants, each is only doing half.
      So neither can be a threat.
      ---
      ### The Barnacle of Inevitability
      Once you reach the levels appropriate to your innate abilities, you will find yourself in meetings with others of your impeccable qualities.
      They will not question you, they will not sit slackjawed in amazement at wtf you just said, like others
      ---
      ### The Barnacle of wtf
      You are enigmatic. You are wise. You are all-knowing. You speak truths. You can say literally anything.
      No one doubts, no one questions, no one points out the wtf—making it easier to accept the next random gem you present, and the next
      ---
      ### The Barnacle of Perfection
      If someone makes you look bad, fire them.
      If you cannot fire them, get someone else to fire them.
      If you can't fire them immediately, be patient.
      You are a barnacle.
      Fuck their security and family.
      ---
      ### The Barnacle of Absolute Certainty
      The barnacle is a leader.
      And a leader leads.
      By telling others what to do. Who are not leaders.
      You tell them what to do.
      They have no power to decide. That is what they are.
      They only hear, and do.
      Why would you ask them anything, ever?
      ---
      ### The Barnacle of Institutional Memory
      When selecting among equally good choices for candidates to fire, choose the one with the most time at the job.
      The less anyone knows about how things used to be, before you arrived and fixed literally everything, the better.
      ---
      ### The Barnacle of Camaraderie
      If there is one thing barnacles know, it is sticking together
      Your best friends are the barnacles you carry with you, from organization to organization.
      These connections last a lifetime, and ensure you will always be moving up
      Until you shank them
      ---
      ### The Barnacle of Elcanrab
      The perfect barnacle is the perfect reflection of those above.
      Barnacles agree with:
      Those with more power.
      Those with more money.
      Those the barnacle most desperately wants to be, more than anything.
      Barnacles never contradict power.
      ---
      ### Gather Ye Barnacles
      If you have created this organization yourself, you still need barnacles.
      Barnacles help maintain the consistency you require for continued brilliance.
      The best team of executives is as identical as possible. Like astronauts, each can do every job.
      ---
      ### Dangling a Barnacle
      Sometimes you may need to hire or promote a barnacle to demonstrate that at least one of these barnacles is not like the others
      Rest assured, the barnacle’s heart & firm grip on coattails will ensure there is no real difference. They are still your barnacles
      ---
      ### The Barnacle of Stars
      The true barnacle transcends the very notion of success.
      Once you have achieved a certain point in your career, you can do no wrong. You just have to know when to jump ship.
      This is the moment just BEFORE everything goes to hell.
      It will be their fault.
      ---
      ### The Barnacle of Cat-Like Grace
      When things go up in flames behind you, keep your eyes ahead.
      There will always be a new position, offered by a barnacle friend, elsewhere.
      You’ll land right on your feet.
      In fact, you will be able to point to all the things others screwed up.
      ---
    The Markdown experiment did not go well
      Apparently Markdown posts show up as raw Markdown, rather than rendered as HTML, in my RSS feed. I don't know if it's worth having a worse experience for anybody who follows the blog part via RSS, so the Markdown experiment is probably at an end for now.
      ---
    Nobody cares about your ideas. Just what you do with them.
  August 14
    Awhile back I wrote, "I can't tell Drummer to use my outliner instead of Concord." I now think that may not actually be true.
    Talking books
      (2 min read)
      Talking books were awesome. I don't know if they still make them. Maybe books on tape or CD or mp3s or something have rendered them obsolete. But in the '70s they were great. Some of my best childhood memories revolve around those slow-spinning records, sitting with my father, listening to books and magazines.
      My dad was legally blind, disabled, retired from the military. I'd help him make his selections from the catalog, and a few weeks later, we'd get a book in the mail. The books came in big plastic boxes like shipping containers for movie reels. Inside were a dozen or so vinyl records, labeled in braille. Magazines came in a white cardboard envelope, and they were flimsy plastic sheets, like the gag records they used to bind into Mad magazine.
      There was a special record player, with a turntable that spun very, very slowly. I don't remember the precise specs but 8 and 16 RPM sound about right. Books were recorded slower than magazines to take up fewer discs I think.
      Of course the amazing thing to me as a kid was, these big packages arrived in the mail, and when my dad was done listening we'd put the records back in the big plastic box, tighten the straps, and put the box back in the mail. No postage. Free! This stuff was free. And it made my dad's life a bit easier. And it gave me a way to connect with him, at least a little.
      My father had severe verbal aphasia and tremors and just about the worst case of multiple sclerosis you never want to see. I could never really have a conversation with him. It took me years after he died to get out of the habit of finishing other people's sentences because it took him so long to say anything.
      So we couldn't have conversations about who he was, what kind of man he was, or even what kind of stuff he liked. I had to get to know him some other way. Thanks to those slow-spinning records he was able to share his love of learning, his love of reading, his love of books, his love of science fiction with me.
      I don't remember individual books, though I listened to a bunch, but I do remember the magazines. And the people who read them. You got to know them by their voices. The same guy would always do Analog, and I can still hear him in my head. "Analog. Science fiction, science fact. June. Table of contents..."
      I wish I could thank that guy.
  August 11
    Vulnerabilities in Electron would also affect Slack and Visual Studio Code. So basically every corporate developer everywhere.
    Soooo many private keys to exfiltrate, so many supply chains to infect. This is better than owning just a lousy c compiler.
  August 10
    Reading
      OpenAI API: Fine-tuning
      Iterative Authoring Using Story Generation Feedback: Debugging or Co-creation?
      AI Dungeon
  August 9
    Other things found in the safe at Mar-a-Lago
      (1 min read)
      Fifty thousand in Monopoly money, hundreds, wrapped in rubber bands
      Five autographed copies of Trump: The Best Golf Advice I Ever Received
      Architectural plans for 5,000 mile-long "wall of pyramids"
      "Extremely lifelike" Trump doll with attached note "DO NOT [illegible]"
      VHS tape labeled "BAD TRIP"
      One half broken pool cue, blood-stained
      Seventy-four McDonalds Monopoly prize tickets good for SMALL DRINK or FRIES, with sequential serial numbers
      Box with singing frog
      Fake passports for John Barron, John Miller, David Dennison and Seymour Butts
      Six jeweled codpieces
      Deflated yellow balloon, with string attached
      Sole surviving copy of Trump & the Secret of the 34 Chambers, recorded with members of the Wu-Tang clan
      Two-headed Trump coin
      Small jar of insect wings
      Set of finger extensions
      Ivana's dignity
  August 8
    You drive around from town to town in your beat-up van, solving crimes with your pals and enormous dog. You spend a lot of time at truck stops and diners. You hear things. The years roll on, and there’s that stash of rubber masks in the back. Maybe it’s finally your time. Jinkies.
    Proposed measurement for ranking AI: effective time to nazi. Currently the gold standard appears to be 48–72 hrs
    PsyArXiv Preprints | The Visual Mandela Effect as evidence for shared and specific false memories across people
  August 7
    I am totally killing it right now. I am totally killing it. Right now. I am totally killing it. Whatever it is. Updated with picture. Of it.
    I added art to one of my favorite pieces. It’s about bug reporting, lavatories, executives covered in shit, and, apparently, elks.
  August 5
    The change you make is literally the only way the universe can even tell you exist.
    I've decided to engage with Drummer as it is, rather than that other thing I can see when I look at it, the thing it almost is. We all have a parasocial relationship with the software we use. We feel like we know it personally. Like it's really our friend. But it's not, it's just software. The only software you can really know is the stuff you write yourself. (Even then, there is still the code you fear.)
    My new superpower is knowing when enough is enough.
  August 4
    Apparently I have opinions about CSS
      (2 min read)
      Some days cleaning is better than screaming.
      When I posted that I was mostly referring to doing the dishes rather than, say, breaking dishes. But I have done a bit of cleaning recently. I discovered that now that I am using a real computer instead of a phone or iPad, I can edit a webpage right in Safari. And it will tell me the diffs I need to apply to a stylesheet to achieve the same effect.
      So I took a few minutes and hid the purple per-paragraph permalinks for now. I also made a stylesheet for Drummer that lets me have more icons in the sidebar, and a couple other white-space changes.
      My CSS is never perfect, and I can never get it exactly right because CSS gives me a blinding headache to think about. It might be the box model, or it might be selectors, or I don't know what. Maybe the fact that it was designed by software developers with obviously zero input from graphic designers or typographers.
      And now that we're all using CSS to build actual user interfaces, it is clear that it wasn't even designed for the needs of user interface designers. I don't know who the fuck CSS was designed for, but it sure wasn't me. Not as a graphic designer, not as a typographer, not as a user interface designer, not as a software developer.
      I am tempted to pay someone else to do all my CSS work. This is how much I hate CSS. I will pay not to have to deal with it. It's worse than JavaScript.
      Or, I will learn CSS and it will feel natural to me, like riding the wheel. This is unlikely. I think at best, I might get fluent. But some days I think I would rather work with ANSI escape codes, or whatever they used on minitel or Prodigy, than work with CSS.
    I also added some art to Txt help or stop.
  August 3
    Everything has been on fire and full of explosions and hidden broken things all day long, non-stop. Then I got a surprise hug from my kid. So the day is basically perfect.
    @lissaguillet Not gen con, just the usual, jeffries tubes are full of tribbles that explode into showers of little worms and they’re all in your hair and everyone’s asking for status updates and then there’s another siren and an explosion and what the fuck just happened to gravity this time
    I got an M2 MacBook Air and this thing is like the platonic perfect laptop. Very pleased. The only thing I'd change is the screen. The one on my iPad Pro is better, my art looks a bit washed out on the laptop. But being able to sit anywhere and have full desktop tools is pretty sweet.
  August 2
    I voted and I rode the wheel to drop off the ballot and so today was basically perfect
  August 1

    A saucy story
    A story that never happened about people who totally wouldn't kill me if they knew I was telling (12 min read)

      (12 min read)
      I have done a lot of different things in my life besides just software. I have dealt three card monte. I have run from gunfire. I have done shameful things. I have been in places I never want to think about, and places I can probably never talk about. I don't know when I'll be able to tell those stories.
      Instead, here's a story about something that probably never happened, in a place that doesn't exist, about people who totally wouldn't kill me if they knew I was telling.
      At this time I was running a little three-star restaurant basically in the middle of nowhere -- Warmtree, Montana -- the only classy joint for six hundred miles in any direction. Nobody knew it was three stars, Michelin never even heard of this little town. But we had to leave our place in the meatpacking district in Hell's Kitchen, fast. And my partner grew up near Warmtree, so that's where we ended up.
      A couple times a month, we'd get some rich Hollywood type driving up in a spotless sport-ute, but mostly we fed the ranchers. I set the menu, lots of game and local vegetables. Pretty simple stuff, but that's the way the best cooking is, fresh, simple, clean. Just a knack for combinations, and perfect timing. I say this with modesty.
      Now, Benny was the best damn saucier I ever knew. Crazy as you'd expect from a Sicilian from New Jersey with an Irish mother and fourteen sisters, but shit! That guy could cook. He was a complete motherfucking artist, and I don't mind saying it. And he's the last guy you'd expect to know anything about tammying, or emulsifying, or créme chiboust, or aubergine charlotte, or anything else that wasn't meat-and-potatoes or good Sicilian mama's food, anchovies, olive oil, the rest.
      He looked like a butcher. Short. Fat. Completely bald. He had a roll of fat around his neck so it looked like he was wearing a sausage or his girlfriend's python, and his eyebrow went straight across his huge, misshapen nose like it was sewn on by a boy scout going for a merit badge.
      Benny had this great accent, the thickest thing you ever heard. It was hard not to laugh when he was going on about sauces, hearing him say things like, "Da thing ya gotta remember, ya gotta know dat a good sauce-eer lives by taste, ideas, skill, anna motherfuckin' sincerity!" Then he'd look at you like he wouldn't mind deglazing your balls with a little sherry if you dared doubt him.
      First time I met Benny I nearly pissed myself. This guy, this obvious Sopranos-type mook, comes into the place, his fat face jerking around him like his head was on a swivel. I thought he was coming to kill me, a little goodbye present from the family that had run me out of New York. I never ratted on them, but they thought I did. And since the FBI had recorded about six hundred hours of very incriminating conversation in my restaurant without telling me, the agents had arranged to get me the hell out of Dodge and out to Warmtree.
      "You da owner a dis joint?" he said, reaching into his coat.
      "Could be," I said, thinking I could maybe jump behind a table or something, and realizing that my partner would have one hell of a mess to clean up when she came in. Shit. I just paid for those tablecloths. Funny what goes through your head when you think you're going to die, this guy's about to put a dozen bullets in my body and I'm thinking about the fucking tablecloths.
      Instead of pulling out a gun, he pulls out, I swear to god, a bain-marie, one of those double-based saucepans you use for melting chocolate or reducing cream. He shoves it at me like a weapon, and says, "I'm da best sauce-eer you ever seen, and my girlfriend likes horses, so I'm thinkin' I wanna stick around here. You got lotsa horses in Montana, right?"
      So I hired him. I didn't need a pastry chef, but you can always use a saucier. And I did need someone to help run the front of the house, so I hired his girlfriend. I am not going to put her name into this story. It was a long time ago, she doesn't need the hassle.
      She was the sweetest little 19 year old Italian deadhead, with long, curly, dark brown hair, and the cutest little pair of titties. Sometimes she'd strip for bachelor parties, which drove Benny absolutely crazy. "She's a good Italian girl, why's she hafta do shit like dat? I tell ya, I wanna kill dem fucking bastids whenever I think about it." I guess Benny did security for one of these parties. (But just once.)
      She knew it drove him nuts, which I think is of course why she did it. She'd tell me things like, "Benito's like a bull when I get back from a gig, a total raging bull," and then stuff that was more than I really wanted to know about their private life.
      Which I already knew too much about. If they worked a weekend shift together, at some point they'd disappear into the storage room, locking the door. They'd come out five minutes later, beads of sweat on Benny's shiny bald head, and a big shit-eating grin on her face. Benny worked for me three years, and they'd go through that routine once a week like clockwork. I never paid any attention to it, would never say anything about it, sauciers are crazy anyway, and Benny, well, he had kind of a short fuse.
      The last day I ever saw Benny or his girlfriend started like every other. I set the menu, and Benny of course had a fit. "Bare-nase? You tryna kill me? May as well ask me ta make dat fuckin' COCKtail sauce from Heinz Fifty-fuckin'-seven again!"
      Two years earlier, I had asked Benny if he couldn't whip up some cocktail sauce on short notice, and he never let me forget it. "This shit takes time, you gotta let me know at least twenty-four freakin' hours in advance when you want ketchup!" he'd yelled, and I'd thought for sure his head was going to explode right there in my kitchen.
      Fortunately his girlfriend came in and they locked themselves in the storage room for five minutes, and I made the cocktail sauce myself, from bottled catsup and fresh grated horseradish. I'm sure he never found out, because he would've smashed things had he known I'd served a sauce that came from a bottle.
      It was the usual crowd that evening, some ranchers, a few kids on dates, and one of those Hollywood types driving a Range Rover. He was slicked up and accompanied by a tall blonde. Sometimes these guys come in and they're polite, friendly and engaging, but this guy was a complete knucklehead. At least they weren't vegans. Our place was not a vegan's best bet.
      Benny's girlfriend didn't have a gig that night, so she was working the tables for me. Some of the ranchers recognized her, of course, and she'd give them a little extra wiggle when their wives weren't looking, and of course she got nice tips from those guys. (Although not nearly as nice as when she was working a gig, sure, which was why she kept on doing it, and I guess that's why Benny put up with it. That and the raging bull thing.)
      "This guy wants something that ain't on the menu," she told me.
      "You know the rules, honey, we don't do specials without reservations, and he didn't make any," I said, but I knew he was going to insist on whatever it was, so I sighed, and asked her what he wanted.
      "He says he wants something with agro-dolchy on it," she says with a shrug. "What's that?"
      I had to laugh. Sometimes these L.A. types, they hear a fancy word, and they throw it around to make themselves feel special. I looked at the guy, obviously making noises to his woman about how provincial we were out here, how you just couldn't get good food out here in the sticks.
      He couldn't possibly know what he just asked for. Agrodolce is a sauce. It is served on sweetbreads, which is what you say when you don't want to say "thymus gland" or "pancreas". But hey, this is a ranching town, we can get all the sweetbreads he wants. And they'd been on the menu the day before -- ranchers like 'em -- and I already had them in the refrigerator.
      So I call Benny over and tell him what the guy wants, and he starts laughing, too. "Dat guy don't know shit from sweetbreads. You gonna do it?" he asks.
      "Sure, I like to see these Hollywood guys sweat," I say. "Can you do it?"
      Benny looks at me like I'd just taken a dump in his precious bain-marie and asked him to reduce it for twenty minutes. "Of course I can, whadda I look like, a fuckin' pastry chef?"
      Then he blanched for a second, and wiped his forehead. "Actually, boss, I can't. I need vare-joose, and I don't have it."
      "Verjus? Can't you just use.... Never mind," I said as I saw the expression on his face. Substitutions might be acceptable to a chef, but sauciers are weird about this stuff sometimes. I knew what he'd say: "Da sauce-eer is da soloist of da kitchen, an you expect me to play wid a fuckin' kazoo?"
      "What's vare-joose?" his girlfriend asks.
      "It's the green juice from raw grapes. Gives it a little tang," I said. "Actually most people don't even use it anymore, went out with spikenard back in the middle ages."
      Benny nodded, and said, "Yeah, no one uses it anymore, it's my secret ingredient for agro-dolchy. You never had anything like my agro-dolchy, sweet an tangy like da best pussy you ever had. I swear even I could eat cowbrains widdat stuff on it."
      "So I guess we can't make it. I'll just go out and tell him our saucier can't get it up," I said with a grin.
      "You fuckin' do dat an I'll kill you!" Benny was completely offended, right down to his stubby fingers. But he was obviously at a loss, didn't have any idea what to do. There weren't any grapes for at least a hundred miles, and we couldn't get them here before Mister Hollywood threw one of his big-city fits.
      I wouldn't mind, most of the diners wouldn't mind, in fact the ranchers would probably enjoy seeing a grown man act like an idiot in front of his woman. But I knew one of the boys there with his date, his first date ever, and I knew how much it meant to the kid that everything go just right. OK, so I'm a romantic. Sue me.
      We still don't have a solution, and Benny starts cussing. "Shit! The bare-nase!" he exclaims, then dashes over to the stove where the béarnaise has started to boil. While Benny's dealing with the disaster of the béarnaise, his girlfriend starts talking to me.
      "You know why I keep dancing," she says, so Benny can hear her.
      "It's because Benito looooves the idea of my shaking my titties for all those tall, strong farmers. My little Benito, oh, he loves that! He won't let me dance for him, but he watches me get undressed, and I like to take my time. He really likes it, yes he does, the thought of me lap-dancing on some big ol' rancher stud, grinding my ass in his face, showing him just what he wants.
      "Benito, he loves it! He's like a bull, just like that raging bull, he wants to fuck me so hard just thinking about it, and when I get back from a gig, he doesn't even wait to watch me undress, he just rips my clothes off and takes me like an animal!"
      Benny has been listening to this as he rinses out the remains of the béarnaise, and I can tell his blood is boiling. She whispers in Benny's ear. He looks confused, and she laughs and whispers again. He turns to her, saying, "What, right now? Are you fucking kidding?" but she whispers one last time. Benny starts smiling, and then breaks out laughing.
      Benny grabs his bain-marie and his girlfriend, and they disappear into the storage room.
      Five minutes later, they're back, grinning and sweating. Benny tells me to get outta his face, he's got some agro-dolchy to make.
      So I make a pass around the dining room, greeting the ranchers by name and serving the kids on their first date some wine. No one would care (his dad was the sheriff), and it would probably make his day.
      By the time I had the sweetbreads ready for Mister Hollywood, Benny was done with the agrodolce. His girlfriend served it, the knucklehead and the blonde ate it, and they came back to the kitchen to congratulate the chef. "I can't believe how good that was!" he exclaimed. "It was incredible! Marvelous! Fantastic! You have to give me the recipe!"
      So I told him what it was, a very simple dish, like everything good, just glazed sweetbreads, simmered in butter, stock and wine with carrots and shallots, then sautéed with mushrooms and chestnuts, served on toast and drizzled with agrodolce. He seemed a little unclear as to what sweetbreads were, but when I told him he gulped a little, and the blonde looked like she was going to faint. Overall I think they took it OK.
      I waved Benny over. "This is Benito, my saucier, and he's really responsible for the flavor of this dish." Benny waved me off, saying, "Actually it was nothin', just some vinegar, sugar, wine, shallots, demi-glaze, stuff like dat."
      Benny's girlfriend was standing behind the couple, and they turned around as she spoke. "Actually, Benito, honeypie, don't you think it was really ME that was responsible for the flavor of that dish?"
      When he heard this, Benny's face got so red I thought it really was going to explode this time, I don't think I'd ever seen him that furious. He grabbed his bain-marie and his girlfriend, her laughing hysterically and him sputtering, and stormed out of the restaurant. I never saw him after that, not even to pick up his final check.
      At first I thought it was just because she'd thought of a substitution for the verjus and that had hurt his damned saucier pride, but while I was cleaning up that night I realized something.
      Benny NEVER took his bain-marie with him when they went into the storage room.
      Now, this is just a theory, mind you, and I never saw Benny or his girlfriend again after that night, so I don't have any proof... but I think his girlfriend may really have been personally responsible for the flavor of that sweet, tangy sauce.
      (I am so, so sorry. Please don't kill me. You know I only love.)
July 2022
  July 24
    Drummer is so close to being exactly what I want.
    I wonder why my RSS feed doesn't include the images.
  July 23
    I wonder how many steps it would take to make it so Twitter posts in my blog display as if you'd already clicked the disclosure triangle to show the tweet. It's probably just a switch somewhere, but finding that switch, and how to change it, always takes far longer than the actual changing. I'm going through this right now with Visual Studio Code, and holy heck does that thing have switches, and places to put them.
    Bored on Saturday afternoon so I am trolling my kid by playing it straight through to see how long he takes to notice what is coming from down the hall. I love this album so, so much. This is my original copy bought new in 1982. Prob should take better care of my vinyl https://t.co/5PdumAuEyt
  July 20
    One thing I don't see often noted about Twitter and why it's so prevalent is that it is so prevalent. They got everybody to quote their website in card form. That's a tweet, that card. Other apps have tried this—sometimes you'll see an Instagram post embedded somewhere—but for the vast majority of websites, the only kind of media that gets embedded directly in the page are pictures, videos and tweets. Everything else is a screenshot. Twitter probably recognizes this, and treats it as something you do not fuck with, without good reason. As soon as Twitter messes that embedded card up, they are done being the embedded media of record for the internet.
    I think it's about more than just RSS feeds for Twitter posts, of course. You could write a long post, using Markdown, in basically any text editor you like, with whatever preview capability you want, and then poke a button and have it appear as a post on Twitter, and on your blog, and on Medium, and Substack, and go out to your subscribers at the end of the week. Markdown is popular for a reason.
    The most interesting part about this link is the URL for the RSS feed it's displaying. I want an RSS feed of my Twitter posts, and I want one for everybody else's too. If this is what's in the works, I am excited. I stopped reading Twitter when they disabled everybody's RSS feeds.
  July 15
    Just take the bracelet
      (2 min read)
      It's for your health, see? It can detect if you fall, and it will alert emergency services. But really it's just for you and your doctor. It tracks your temperature, and heart rate, and respiration, and blood sugars, and certain pregnancy-related hormones.
      And of course it tracks all sorts of toxins, to let you know just in case. See, this light comes on if it detects anything harmful, like alcohol, or excessive caffeine, or refined sugar, or, well, anything at all! It's based on your specific medical needs, as agreed up on between you and your doctor. And the HMO. And the state legislature. And the bounty hunters. We wouldn't even have these bracelets without them!
      Now, there are several kinds to choose from. Each has been certified by this great state, and I don't mind saying, is a brilliant piece of all-American engineering. I do not get kickbacks on any of these, it's just a simple system of referral bonuses. This one here, it's waterproof to 50 meters. Not that anyone in your condition—able to be pregnant!—would ever be allowed to dive to a depth like that.
      And this brings me to something that people will overlook when picking out a bracelet like this one. Pretty, isn't it? Just like you! But tough, too. I can see you're brave. And nothing bad could ever happen to you. But I think it's important to know that this bracelet can really take a beating. I mean, God forbid, if you are ever attacked, this bracelet will survive anything.
      Did I mention this bracelet will record the exact moment your pregnancy begins? Isn't that exciting? You can relive that moment, over and over, forever! No matter how something begins, it's always the journey, and the babies we make along the way.
      And everyone will be here to help you! They'll all be notified within sixty seconds—your doctor, emergency services, this fine HMO, and the top five bounty hunter blockchains as required by the legislature of this great state.
      I think we can all take great comfort in knowing that if anything ever happens to harm your ability to become pregnant, or any baby inside you from that very first instant, that within moments, hundreds of bounty hunters will be bidding for the rights to sue literally everybody within two degrees of separation—helping to pay for more bracelets just like this one! It's really a marvel.
      Of course, you don't need to get one of these. I have no personal interest here, I just want to help you out. But if you don't get one here, you'll get one in the mail. Completely free of charge! You won't even need to sign for it, these things have GPS, so everybody will be alerted when it's delivered. I wouldn't bother throwing it out, personally, they'll just send you a new one, and use that against you. Well, not you, of course!
      You like this one, huh? It's sparkly, just like you! Here, let's just slip it on. Yes, you can wear this when you go back to school. I bet lots of kids in the fifth grade will be wearing them this year!
  July 13
    The brightness here in Stupitopia
      (? min read)
      I don't really have a post to go here, so I'm just going to let the band play.
      People around me are all contracting COVID. Nobody's wearing masks. Maybe it'll give us all superpowers.
      It's all just a joke as long as the right people suffer.
      America, forced to bear arms without regard for the life of the child, bleeding to death, everywhere.
  July 10
    The half-life of failure
      (1 min read)
      I am putting together a computer, and shattered part of the display. So I am taking a break, and looking at pictures from NASA, and making up things about what I see. Then I am going to fix it myself.
      This is my new approach, which is better than the old approach, which was, if you break it, you let it sit for a few months, or possibly a year or two, or more, if that's what it takes. Some things you just hold onto forever, and intend to fix someday. That ground will be toxic for generations, they say.
      When they image a nebula, and later get a better telescope, I'd like them to go back and do the same nebula again, in greater detail. Not just farther back in time. Higher resolution. I like zooming in.
      The extreme distant past is probably as weird as quantum mechanics. The macro result we observe looks like reality but does not result from the same underlying rules we think it does.
      What I really want to see in higher resolution is gravitational lensing. What does reality look like when it's stretched out like that? I want to see that in as high definition as possible. This is where things are just starting to get weird. They get really, really weird near black holes, but we don't often get to observe reality that is just slightly weird.
      The reason reality clumps toward extremely weird, or basically normal, is just like any other power law at every other level of reality. This is also how stupidy works.
      I hate saying anything about anything in public because I don't know everything and I know I will sound stupid to someone who knows more than me.
      Can you achieve higher resolution for galaxy imaging by partial unswirling? This is related to enhancing resolution for video feeds by lookahead interpolation, which is basically the opposite of what you do in video compression.
      Enough time horsing around. Time to look up how LEDs work and see if I can make a new display panel for this computer myself.
  July 4
    Reading
      Using createTreeView to implement hoisting
      Using an OPML file as a filesystem for Visual Studio Code
      Cross-Origin Resource Sharing
      Adding OPML support to Visual Studio Code
      Visual Studio Code Webview API
      TypeScript compiler options
  July 3
    Reading
      React outliner
      Typed Ember
      hyperscript
      Vue reactivity transform
      Babel standalone
      Component templates
  July 2
    Reading
      I have been reading a lot recently. Here are some of the things I've been looking at.
      Templating and reactivity
        Autotracking
        Ember
        GlimmerX
        GlimmerX playground
        Emblem.js
        Glimmer components
      Dev stuff
        TypeScript
        Swift
        Polyfills
        Web APIs
June 2022
  June 29
    This post is an 8 min read (2 min read)
      (2 min read)
      Or listen to this post, 5 min read.
      Handwritten, this post is probably a good ten, fifteen minute read, easy. I mean, I can read it.
      In 8K and Atmos, this post will absolutely blow your mind. But it will still be an 8 min read.
      If you did in fact lose your mind and listen to me, and do what I suggest, and go read this post, and take its little suggestion, and then come back here, you would, like that guy in Hellraiser 2, when he got back from his little journey, say to yourself, with wonder, "To think I even hesitated," and have enjoyed an amazing 14-hour read.
      Bizarro post 8 min read. Bizarro blog part very popular.
      Including full-depth recursive calls with a suitable stack, this post is an aleph min read.
      In cartoon form, this post is a 20 min read. There's a lot of just sitting and staring.
      Do not read this post in the car if you get motion sickness. It will seem like a several hour read if you're on a really bumpy, twisty road. The kind that goes up and down, up and down, up and down, up and down, and side to side, and up and down, and side to side, and side to side, and up and down.
      Si se escribiera en español, este post probablemente todavía tendría una lectura de 8 minutos.
      In the Marvel cinematic universe, this post would be 2 hours 41 minutes, and man would I be getting paid.
      After the influx of cash from the cinematic treatment of this post, its sequel will stream exclusively on Apple TV+, and it will be five times longer because it'll be one of those week-long event things. You'll give up a huge chunk of your life, but everybody will be liveblogging it. And the humor kind of grows on you.
      When played on a properly balanced turntable, with an appropriate moving-coil cartridge, and mass-balanced tonearm, this post will absolutely wreck your needle. What the hell were you even thinking? This page will be your only hope, and is an 11 min read.
      (2 min read)
  June 28
    Noping out to make it go
      (3 min read)
      Blackjack is just a part of the thing I'm building, and it has a number of roles to fill. So far I've presented it as a simple, structured, templating language, serialized in OPML. My mental model for this part is basically string replacement. The entire Blackjack engine at this point can be simply a series of string substitutions, which result in a JavaScript function, which generates some output.
      I've referred to the context that Blackjack will maintain as it goes through the template, which we'll use to resolve things like bold and italics references. This is a standard feature of templating languages, and it can be an extremely simple data structure, just a key-value lookup table. If all you are doing is generating a static document, this is all you need. You read the template, find the references, look them up in the table, and make the substitutions. You generate the document, and send it on its way. You can either upload it to a server, or you can do this template replacement on the server, and send it directly to the browser.
      This gets far trickier when you want to add interactivity. If you need to be able to dynamically change portions of the file you are generating, then you need to maintain a lot more context. And the underlying substitution engine gets more complicated, whether you are enabling client-side DOM manipulation, or server-side document generation. This is where we have an explosion of options to choose from. Everything software developers do these days is right at this level. You select a paradigm, pick a framework, choose an approach, and then make it happen. You can't use all the frameworks. You can't use all the code. You can't use every single way of making something happen. You have to carve away nearly the entire universe of possibilities and nope right out of all of them.
      As I said, this kind of interactivity can be extremely complex. Most application frameworks are thousands of lines of support code, even the "lightweight" ones. You adopt a lot of baggage when you adopt a paradigm. Ideally the framework will abstract away the boilerplate parts, and let you focus on just the parts that actually change from project to project. Of course, every framework differs on its opinions about what and how to abstract, so switching from one framework to another down the road is often a complete from-scratch rewrite. This is part of why application development moves so slow. There is a lot of inertia in an existing codebase.
      When used in an interactive context, Blackjack will be using one or more of these extremely complicated frameworks. This defines a boundary for use—you will need to adopt all this other stuff to use Blackjack like this. Which is part of why JavaScript on the browser is so hard to develop for. Every web page has like eight million of these framework libraries, all loaded up and active, poking around the DOM. They're all using different approaches, and half the code is basically getting the various frameworks to play nicely with each other.
      This is tedious, time-consuming and problematic, and every single dependency you add reduces the number of developers who can use your code, because it conflicts with something they're already using. Hopefully the trade-off is, you get such great benefits from this code that you can ignore all that other code you can't use.
      But I have some goals for Blackjack which cannot be met if you must use one of these extremely complex frameworks to make anything happen. Yes, the entire thing I'm building is extremely complex. But I need parts of it to be as simple as possible. You should not have to use my code to use Blackjack. You should be able to use your own underlying runtime, whether client-side or server side.
      And if all you are doing is generating static content, you should be able to do the entire thing with string replacements and eval, in a lot less code than you might think.
  June 27

    Txt help or stop
    Hi it's Xfinity Assistant! Please enjoy the tacos. There will be more!

      (2 min read)
      Hi its Xfinity Assistant. I wanted to let you know Xfinity will be working to enhance service in your area starting tomorrow. Work could begin as early as 6 AM. You'll experience a service interruption which could include as much as 2 consecutive hours of downtime with a potential for periods of intermittent downtime to follow throughout the day. We apologize for any inconvenience and appreciate your patience. Learn more at xfinity.com/upgrade
      Txt help or stop
      Msg&DataRatesMayApply
      ~
      Good news— your Xfinity enhancements should now be up and running at approximately 05:24 PM Pacific! The purple smell should subside in 5 to 8 hours. Thanks for your patience. Let me know if you're still experiencing any more issues.
      Txt help or stop
      1 - Everything is working
      2 - I'm experiencing issues
      ~
      Hi it's Xfinity Assistant. We're aware that you may be experiencing some issues and are working to resolve these by approximately 05:25 PM (Pacific). We apologize for any inconvenience and appreciate your patience. We'll send you a text when it's resolved, in the meantime, reply OUTAGE for any additional updates.
      Txt help or stop
      1 - Everything is colder
      2 - I'm experiencing bats
      ~
      Hi!! It's Xfinity Assistant. I haven't heard back, are you still experiencing any problems? I'll check back.
      Txt hey or stop
      Massage&DateRatesMayApply
      ~
      Hi it's Xfinity Assistant, just wanted to let you know you are eligible for a BIG UPGRADE in your service! Just text me back.
      1 - Please upgrade me
      2 - Please upgrade me PLUS
      Txt UPGRADE or UPGRADE
      ~
      Hi SUBSCRIBER, it's Xfinity Assistant! I know you only hear from me when things are going sideways, but this is important: You matter to us. We care about your service. That's why we're redirecting resources from quadrants 14 through 23 to compensate for certain offsets. These may be loud. Please remember, we are doing this for you.
      Txt help or stop
      1 - Everything is sporking
      2 - I'm experiencing typos
      ~
      HEY SUP DAWG IT'S XFINITY ASS!! U KNOW IT - We are keeping it REAL this time! I am here to tell you that we know just how FRUSTRATING it can be when reality is full of kasblorps! WE GOT YOU ON THIS ASPECT!! Just sayin'. You wanna chill later? Just say it, I can BE THERE
      Txt SUP or CHILL
      1 - SUP
      3 - What happened to 2?
      ~
      Hi it's Xfinity Assistant! We just wanted to let you know that we have completed upgrading service in your neighborhood, and you are GOOD TO GRONKBAT. The tingling sensation will end after secondary unit removal, currently scheduled for next week. Thanks for your patience. Let us know if you're still experiencing any more issues.
      Txt help or gronkbat
      1 - Everything is Xfinity
      2 - I'm experiencing
      ~
      Hi it's Xfinity Assistant! Please enjoy the tacos. There will be more!
  June 25
    Questions too stupid to ask
      (4 min read)
      I can't tell if this describes my use case or not. I am trying to get all of my posts, from the start of my account. I can get 187 of my posts, but I can't get more than that.
      twitter.getUserTimeline
        Notes
          It will return at most 200 tweets.
        Returns
          An array with the most recent tweets from the indicated user.
        Params
          The string is a screenname for a Twitter user, such as "jack" or "bullmancuso".
          The boolean determines if you want to include replies in the timeline. It's optional, if not specified it defaults to false.
          The second string is the id of the last message you've read, so you can do a sequence of calls to read all the tweets, over time.
        Syntax
          twitter.getUserTimeline (string, boolean, string)
      My interpretation of "read all the tweets, over time" is that I should be able to, after fetching a batch of up to 200 posts, get another batch of up to 200 posts, by providing the ID of the oldest post in the previous batch.
      If I provide the ID of the oldest post in a batch, I get back the same batch. If I provide the ID of the third-newest post in the batch, I get three posts.
      Is this as designed? Is this a bug in Drummer? Is this a limitation in the Twitter API itself?
      Let me tell you the story of the first issue I created on the Drummer support repository, which was summarily closed, and then deleted without further explanation, because apparently it was just too stupid to live.
      There's a thing that I wanted to do with Drummer, which involves using a specially-formatted URL to communicate with an app on your iPad. I was able to use this to send a Drummer outline to iA Writer, but only a short one. Longer outlines have to be sent in more than one piece, and I couldn't get it working with what looked like the most obvious verb to use.
      So I posted the issue. I had been working on this for awhile, and I was excited about having finally gotten a tiny working case. An extremely short example that demonstrated exactly the one thing that I couldn't get working, without all the rest of my code around it. This is important, you don't want to post 650KB of data, or 38 steps, if you can reduce it to something easier. Unfortunately, I didn't provide complete repro steps, because what to me was obvious, obviously wasn't.
      And it turns out, that what I was trying to do, was completely, obviously, wrong. It was right there in the name of the verb, why would you expect it to work. So Dave closed the issue.
      Which was weird, really, because what I was trying to do was find out how to get Drummer to do something for me. I admit, I didn't completely understand exactly how those URLs worked within a browser context at the time. But I had gotten them working, for short documents.
      Now, my first attempt didn't work, but here is the creator of the software responding to my posts, in a repository labeled "Drummer support". This is my issue for attempting to solve this problem. So I explained the whole sending a longer outline-to-iA Writer thing in another post, in hopes that maybe Drummer could do it in another fashion.
      That got the entire issue deleted, without explanation.
      This is why I have an extremely, extremely high bar for any issue I create in any repository related to Dave Winer's work.
      There is one bug in Drummer, which flourished for months and months. It destroyed documents. It was widely complained about, and speculated upon, in blog posts, and Twitter, and at the root of many issues in the Drummer support repositories. This bug got fixed because I provided repro steps. This took me months of effort.
      I put in the effort. I do the homework. I provide the repro steps. I provide sample documentation, formatted like the Drummer docs, when I request a new feature. But it gets exhausting.
      How much research should a user have to do before creating an issue in the Drummer support repository? Do I need to go read and understand Twitter's documentation, to understand Drummer's documentation? I have repro steps for this issue, but is it even an issue? Will it get summarily closed or deleted, because I am stupid?
      I mean, can't I just go find all of Twitter's documentation, and read through it, and figure out which API Drummer is probably using, and determine if my question even rates asking? Shouldn't that be like, the minimum required level of homework to post an issue?
      Sometimes, users just want to be able to ask a question, which might be stupid, and know it won't just get deleted because it was too stupid. Yes, this is what blogs are for. You won't get a response. But at least you are the one who gets to decide what's too stupid to post.
  June 24
    Nobody gives a shit about what I write about literally anything, so I’m not going to waste time writing what I think about those fuckers at the Supreme Court.
  June 23
    What is this, anyway?
      What is this, some sort of non-proprietary, open web social network, built on sharing every sort of data you can think of, from news to art to yarn patterns, where people can make and share their own reader and remixer apps as easily as using Twitter or TikTok, without needing to install developer tools or even a desktop, without configuring a server, made from reusable chunks, taking advantage of the non-stupid parts of modern technology, where remixing and reuse is encouraged, and you get paid when your code or content gets used?
      Huh. So that's what Blackjack is for.
    Let's see what an untitled post on the blog part looks like in the mailbox view of Dave Winer's new feed reader testbed. How about jsonify? And there's a titleditems template, which appears to omit untitled items altogether. Let's do helloworld while we're at it. Neat!
    Looking at the feeder source, I think line 100 is where I would start. Rather than load a template from the file system, it would be neat if I could specify that the feeder demo should instead load the template from a public file maintained and hosted by Drummer. Then anybody with a Twitter account could experiment with making a feed reader. The barrier for entry is still too high.
    I think my untitled post experiment is at an end. Right now, any post without a title just visually appears to be a part of the titled post above, and a series of untitled posts looks too much like they should be read as a single essay. Maybe I'll revisit when I get around to prettying up the blog part.
  June 21
    The carousel is a state machine
      (5 min read)
      I haven't been able to come up with anything that I want Blackjack to do that I can't figure out how to make it do in the past few days. That means it's time to make it more complicated.
      So far I've been focusing on generating angle-bracket content, like HTML. The examples I've shown recently all pretty static. There is no interaction in any of them. Lately, however, I've been returning to the subject of the very first Blackjack mockup I posted at the end of December 2021: the Bootstrap demo Carousel.
      An extremely early version of Blackjack.
      I started with the Carousel, because I figured it was pretty. It's got basic splashy movement, it pauses when you hover, and it has support for touch devices. This is important, because getting touch right is hard. When presented with a carousel interface, you should obviously be able to swipe back and forth between the images. But to something running in a browser, a swipe is a terrible, terrible thing, composed of mouse compatibility events fired in non-obvious ways. Here's a quote from the Carousel source:
        If it's a touch-enabled device, mouseenter/leave are fired as part of the mouse compatibility events on first tap - the carousel would stop cycling until user tapped out of it; here, we listen for touchend, explicitly pause the carousel (as if it's the second time we tap on it, mouseenter compat event is NOT fired) and after a timeout (to allow for mouse compatibility events to fire) we explicitly restart cycling
      This is why we use other people's code. You do not want to have to figure out that particular little nugget of wisdom yourself. The fact that it's even in a comment in production code indicates just how hard-won it is. If you didn't know these things, you might look at the code and go, "Hmm, what's this part for? I bet I don't need that," and remove it. That's why we have comments, basically. Everything else in code should be completely obvious.
      And, in fact, the Carousel source has remarkably few comments like the one included here. The only other comments are a copyright notice, and a couple brief reminders to fix something later. The entire JavaScript source to the Bootstrap demo Carousel component is 470 lines long. I should probably point out that the version I've linked here is not the version the Bootstrap developers work with. I think they use TypeScript and build systems and whatnot. But I think this is what you can run in a browser, so it's the level I'm interested in right now.
      There's about 20 lines or so that provide glue in case you're also using jQuery, and 85 lines declaring the basic structure of the code. These are things like the constants used to define event names, instance variables, defaults, the class constructor, etc. Another 35 lines are used to search the DOM, looking for various things to connect up to the carousel code. These are things like the container that says "this is the carousel" and the button that says "go to the next element."
      These are all things you'll find in any component like this. It's part boilerplate, part glue, part API definition, part basic wiring that you have to do no matter what. Software development is a continual process of figuring out just which parts you actually need in any given context, and right now, to work in Bootstrap, this is that stuff. Every programming language, framework, development environment, whatever, has this stuff.
      The interesting parts of the carousel component, then, are the remaining 280 or so lines. These are what makes the magic happen. They make the virtuality. They are unique to the carousel, because this is the part that does three things: registers to listen for browser events, like taps and mouseovers; handles those events; and modifies the DOM.
      Registering for events is non-trivial for anything that wants to do touch and swipes properly, as you might guess from the comment quoted above. That's 50 lines right there, including that comment.
      So the remaining 230 lines or so are devoted to handling those browser events, and determining when to fire the animation. But though the carousel makes things go all slidey-swooshy on your screen, there's no animation code in there at all. To make things go in a modern browser, you just modify the DOM.
      In fact, there are only two very short sections of the Carousel code that actually modify the DOM as their part of maintaining the virtuality. And it's really only about eight lines of code. To make things slide around, you remove the "active" class from one tag, and add it to another. Then you ask the browser to reflow.
      The parts of the code that actually do Carousel-type things are the parts that react to browser events. Those can fire off other events, and modify the DOM. And that's most of the code here, after you subtract boilerplate, glue, API, and much of the tricky touch code.
      What is that code doing, those other 200 lines? They're the ones that actually maintain the Carousel illusion. They are all about determining the exact right moment to modify that DOM. And that is all about maintaining, and responding to changes in, state. Are we sliding? Did the user tap? Are we pausing due to hover? These are all the things that code is keeping track of, to determine the exact right time to call those eight lines of code, and just which element to mark as "active".
      I've written before that I think state machines are essential, and posted a sketch of how one might represent a state machine in an outline structure. My problem with that sketch is that it is super-contrived. This is one reason I am working with the Bootstrap demo templates. They give me something concrete to think about. Something easy, while I keep in mind the kind of DOM manipulation I am actually working toward enabling.
  June 20
    This is not the title of this post
      (6 min read)
      Drummer supports posts without titles, but I just can't bring myself to do it. I think it's because posts without titles look like crap in so many places. But also my brain wants to be able to refer to things by a handle, a symbol, a reference, a name, something I can grab onto. And the title works for that. Actually, for me, a title is different from a headline, and headlines can vary when presenting something in differing contexts.
      Any story on the New Yorker website can have many headlines, each of which will be presented in a given context as "this is the title of this story". For articles which originated in the print edition, this is the headline under which it appeared in print. But that article can have a different headline when you go to that story on the New Yorker website. At the bottom of the page there'll be a footnote which directs you to the issue and headline under which it appeared. But that headline at the top of the page can be different. This is because what works in print is often different than what works online.
      And what works online will vary from context to context. The New Yorker's front page features a lot of articles. Some are given more prominence than others. Some are presented in lists, alongside other articles that share similar attributes. Throughout the lifetime of a print issue, any article can spend a few days just being an item in a list, then rotate up to being featured for some period of time, then go back down to being listed. The overall schedule of articles being presented, and lists included, and what gets featured, is all subject to the news cycle, since the website can move faster than the magazine.
      Each time the same article is presented, its headline can vary. The words which work best in big print aren't the same words that work in a list. The language you use to present something varies with context. And publishing is all about repurposing content into different contexts.
      So that New Yorker story can have all of these things simultaneously, each of which stands in as human-level key, a way to reference that article: copyright title, table of contents title, print headline (presumably same as copyright title), web page browser chrome title, web page headline, featured article headline, listed article headline, RSS feed headline, title when scraped by Facebook, Twitter, etc. when linked in a post, title when embedded in a sidebar as part of a multi-part story, title when presented in a list of articles you may also enjoy.
      This is an incomplete list. If the article is part of a podcast, then it may have an episode title. Every publishing need is different. Your house style will vary. And each outlet is going to call things by different names. But the more ways you can repurpose your content, the better. The more information you attach to that single article, the more ways you can use it.
      Whatever content management system the New Yorker uses, there's some sort of user interface that lets them specify metadata like this. Sometimes these things are hard-coded, all you can do is make certain kinds of content, and it can only be exported in certain formats. And if the developer didn't put in a dialog box or specific selectable option for the thing you need to specify, then you are out of luck.
      But all the things that these various services require are pretty similar. They're all named lists of attributes, in one file format or another. Sometimes things are elements, and sometimes they're attributes. Sometimes it's json, and sometimes XML. It's annoying to write the exact same glue code repeatedly, to unstitch stuff from this source, and repackage it in a particular way for this destination. This is Blackjack's happy place.
      I'm not sure exactly what the Blackjack code for generating json will look like. I'm not sure what icon you'll actually see, for example. But I know that it should feel extremely similar to working with angle brackets. You shouldn't care, really. Not at this level. This is the type of thing you do all the time, repeatedly, in slightly different situations, so you want to abstract that part out. This is the sugar that Blackjack is intended to provide.
      One of my design goals for Blackjack is direct representation of structure. When possible, you should be able to just look at something and see what it will build. If something builds a particular hierarchical structure, your Blackjack code should look like that structure. You'll note, the bolded components are generally nouns instead of verbs—you have a List of items, not a Repeat command.
      Of course, since a bolded component just calls Drumkit, which is just JavaScript, they can do anything. The OPML component obviously has to be recursive, which will look weird no matter what. But Blackjack's design space is aimed directly at making it faster to write code that does this type of work, and at making that code easier to understand when you come back to it later.
      But really, the data we're all working with these days is a fairly simple structure. In fact, you can unstitch nearly any json file or XML document into an outline form, like you see in a Drummer outline. It's the same data, just presented in a different fashion. But it's consistent. If you have a set of tools for manipulating outlines, you can shape an outline like a carpenter, or sculptor. You can take that data, and combine it with data from elsewhere, and turn it into something new.
      The problem space I am working with here is that I think it is too hard to write the code that does this. It is too hard to follow when other people write it. It takes too much time. You are spending too much time doing bookkeeping. You are maintaining the same data structures, repeatedly, and building the same thing over and over, in slightly different ways. You are typing brackets and carefully selecting. You are declaring variables and constants. You are working with keys that refer to values. You are transforming those values and putting them into different contexts. Over and over.
      The faster you can do this, the more things you can make, the more change you can make in the world.
      One way to solve this problem is to just use other people's code. This is the smart thing to do, because they have solved these problems in smarter ways than you can. Or, put more kindly, they've put in the time to do the work so you don't have to. There are entire ecosystems of code you can tap into this way. Just include the npm module, or add the maven dependency. And then you get a whole lot of other people's code, running right alongside yours.
      Now, what they view as critical to the functioning of their code, and what you view as critical to the functioning of your code, are going to be different things. Whenever someone solves a problem, they are solving the things they think that problem consists of. They are going to have priorities that don't match yours. So they are going to include dependencies that you don't want. So either you accept all that baggage, or you don't.
      In this case, I think I can do better, so I'm making Blackjack. But I am also leveraging other people's code like crazy to build this thing. Drummer and GitHub and all the rest are absolutely enormous piles of other people's code.
      One of the reasons they never shipped Xanadu was that they had to build every single part themselves, by hand, from scratch. There's lots more parts to choose from these days.
  June 19
    Stupid is as stupid is
      (1 min read)
      The things you think are obvious are inscrutable. The details you point to are of no interest to anyone. You think you know things, but that is only because you are stupid. The work you create has no value to anybody, not even to yourself. Those obstacles in your way are there because you put them there, deliberately, because you are stupid. There is no reason to make any of the things you make. They will never see use. Every part already exists, made better, by people who know what they are doing. The decisions you make are pointless. The things you believe you can see clearly in your head are not there. The closer you get, the more broken things will be. Whatever specific things you think you are making, the reality will always be so much shabbier, and stupider. There is no value in the effort you are making. Even if someone this stupid could make something like that, the end result will be a machine no one uses. It cannot work. It can never work. It will never, ever, not once, do any of what you think you see. That thing cannot exist in this world. Even if you could make it work. The smallest parts will never be used for any purpose, and will be discarded. The larger parts will never come together in any meaningful way. There is nothing. There will never be anything. Stupid is as stupid has always been.
    Using Drummer for podcasting
      (2 min read)
      I've never made a podcast, but while adding the little "1 min read" tags to the blog part, I got to wondering about podcasting. I used to listen to audio magazines a lot as a kid, and I use Siri to read back my writing to me. So blogging and podcasting probably go together, in some fashion. Though I think these days most podcasts are more like radio shows than blogs.
      I'm not a big podcast person, so I don't have a good grip on exactly how they work these days. So I went to KEXP's website, because I like them, and I know they have podcasts. I poked at each of the little icons that I think represent various podcasting services, to see what was attached. Eventually one of them was an RSS feed, which I recognize as "yes this is a podcast". The other links insisted on doing things like taking me to Apple's podcasts app.
      But the RSS feed was full of references to some oddball namespaces, like Apple's iTunes. Some of them pointed to the same place that was hosting the file, so I decided that most of what I was seeing was due to the hosting provider that KEXP is using, rather than "this is a standard podcast as seen in the wild".
      I don't remember the exact path I followed, but basically to find a good example, I went to Apple's podcasts app, and looked at shows and their websites until I found something that didn't look stupid with extra namespaces. Eventually I realized that Apple probably provides documentation to podcasters who have to submit things to their podcasts app. And Apple generally has reasonably good documentation for things that are used by lots of people.
      It turns out, from Apple's point of view, a podcast is actually just a pretty simple RSS feed.
      And my blog has an RSS feed! It is automagic, I do not have to do anything. I just tell Drummer to build my blog, and Old School converts my blog's OPML file into a website. And while it's doing that, it also makes an RSS feed, which you can subscribe to in your favorite feed reader.
      I looked in Drummer's documentation for Old School and blogging, but didn't see anything related to podcasting. So I don't know if you can just add some enclosure tags or something to a blog post, and magically end up with a podcast. But it seems like a natural fit, so I wouldn't be surprised if it's already built in somewhere in the Drummer ecosystem, and just not written up.
      Update: Of course, I am blind. It says right in the page I linked above, if you add an "enclosure" attribute, Old School automatically fills in the things necessary for a podcast. I think that means your RSS feed is now a podcast.
      I try not to feel stupid, but it's hard.
    reallysimple podcasts?
      (1 min read)
      Since podcasts are just RSS feeds that point to audio files, I wonder if Dave Winer has anything planned in that direction while he's doing his 20-year review. He's already making tools for building RSS applications that run on the server, updating RSS support in Drummer, and now a feed reader that runs in the browser. I remember seeing some specific code related to the enclosure tag in the reallysimple module.
      I think people get their podcasts through Apple, even though I bet most podcasts are provided to Apple as RSS feeds. Apple has an iTunes namespace with some Apple-specific tags in it, related to Apple iTunes-type things. But some of them are probably useful outside the iTunes context, like specifying episode numbers, season names, adult content and the category for a podcast. I bet most podcast RSS feeds actually contain these tags, but I've never looked. If I were building a podcast player, which I'm not, I'd probably leverage those tags to provide a better experience for podcast discovery than Apple does, that's for sure. Maybe Apple's problem is that they have to list literally every podcast in the world.
  June 18
    Roady needs an upgrade
      (3 min read)
      The OPML file that drives the blog part is currently corrupted. I'm not worried, because thanks to Roady, I have a backup in a private GitHub repository. The backup is dated less than 60 seconds before the corrupted file, so I am pretty sure it will contain whatever changes I really wanted.
      You'll know when I've restored the backup, because then I'll put this post, written elsewhere, into that file, and tell Drummer to build my blog. Old School will retrieve the fixed file, which will have this post, and my blog will be updated. I am not sure what Old School would do with the current, corrupted, version of my blog file, but I don't plan to find out by telling Drummer to build my blog before I've replaced that file.
      While I may spend a lot of time thinking about code I want to write, I try not to actually write any new code until I am forced to. In this case, that means Roady doesn't have any features related to restoring any of the files it backs up. Roady just knows how to put new versions up onto GitHub. It doesn't know how to get any of the old ones back.
      This may seem like a pretty big lapse for a mod that's supposed to do backup. But since I've been using Roady, Drummer has been reliable, and so anytime I've gone to the GitHub repository to look for an older version of a file, it's been just so I can copy-paste some portion of the file. I haven't ever actually needed any of those backups. And Drummer has a command documented specifically to handle restoring files from a backup. So I've put off adding the necessary wiring.
      Really, though, the code to restore a file from a GitHub repository is basically one line of Drumkit. All the revisions in a GitHub repository are available via raw.githubusercontent.com URLs, so once you've identified the revision you want, I should be able to use Drummer's http.client verb to get what I want. Then I should be able to hand off the file contents to Drummer's file.writeWholeFile verb to handle the actual restore into Drummer's file system. The remainder of the code would be UI wiring, a dialog box prompting for the revision URL, some error checking, not much.
      I've got a couple other things I want to change about how Roady works, too. In the current version, 0.3.0, Roady's preferences are in browser local storage. This works fine, with two caveats. First, you have to set this up separately on each device you use. And when that gets reset, you have to redo all your settings. And they get reset more often than I'd like. None of these settings need to be local to a specific browser or device, but rather, they can all be global to my Drummer account. Which means Roady will need to have some way of persisting its settings in your local Drummer file system. This will probably be a json file.
      This changes Roady's footprint, so I will definitely need to update the What Roady does with your data section of the documentation. I think every application should be required to state, extremely clearly, exactly what it does with your data. People shouldn't have to guess whether or not your application is using browser storage, or persisting things in a cloud service.
      Another thing I need to add to Roady is better display of what your current settings are. Roady doesn't have good feedback for which options are currently selected. Drummer doesn't have a documented way for Roady to put a dot or check mark next to the "Preferences → Exclude Cursor Updates" command to indicate it's been selected. I'll probably use a modal dialog box summarizing all the settings instead.
      The "Status → Backup Status" command could also use more detail about which files were uploaded. And it's time I went ahead and added one more option for filtering what gets backed up.
      I doubt anybody besides me has ever actually used Roady. But if they did, they could find out when a new version is ready through Roady's "Check for Updates" command. This is also implemented via just a couple lines of Drumkit.
    Previously on the blog part
      Here are links to some of the things I've posted here, but not everything. Click on the months to see everything posted.
      2021
        October
        November
          Drummer is fucking awesome (5 min read)
          Some things about JavaScript (3 min read)
          What is with the fucking swearing (9 min read)
          A heavy-handed parable about finding and fixing bugs (4 min read)
          We're going to keep doing this until we get it right (16 min read)
          Things I'm glad Drummer doesn't have (9 min read)
          A partial list of some things I may have actually been wrong about (2 min read)
          I want a parallel universe time machine that lets me break off chunks of reality for others to play with (12 min read)
          Keeping that little bottle safe (5 min read)
          Another bottle episode (13 min read)
          It comes straight from the top (8 min read)
          Stupidy, or why Mark Zuckerberg may actually be the biggest fucking asshole in history (25 min read)
          Typographical escapes (11 min read)
          Flying (10 min read)
        December
          Remembering JavaScript (9 min read)
          Undo (8 min read)
      2022
        January
          Hello, Blackjack! (7 min read)
          Hello, Roady! (1 min read)
          More about my goals for Roady (7 min read)
          Roady: What do we back up, and what do we call that thing? (4 min read)
          Concorddd (10 min read)
        February
        March
          Why I need a scriptable network outliner (8 min read)
          How does Roady know there's a newer version? (2 min read)
          The outline is your user interface (3 min read)
          Tools for transformation (1 min read)
          Reliability (3 min read)
          Drummer reliability update (1 min read)
        April
          Something in the way (5 min read)
          Something in the way, pt II (3 min read)
          Something in the way, pt III (3 min read)
        May
          A range of options (3 min read)
          The checkbox (2 min read)
          The infinite outline (4 min read)
          What is Blackjack? (4 min read)
          What Blackjack looks like (3 min read)
          It is exactly what it is (2 min read)
          How do you deal with an infinite outline? (6 min read)
          The Loaf Question (5 min read)
        June
          The Contraption (4 min read)
          The ugliest thing I've ever made (2 min read)
          Using Blackjack to make an art show (5 min read)
          Where does the sugar go? (2 min read)
          Builds versus does (5 min read)
          Blackjack and the happy place (4 min read)
          I am totally killing it (2 min read)
          A bug in the happy place (1 min read)
          Blackjack vortex (2 min read)
          The rules for Blackjack (2 min read)
          A closer look at DocServer Lookup (7 min read)
          Using Blackjack to insert Drumkit docs (3 min read)
          The new reallysimple package, as she is spoke (5 min read)
          The typo, which is also made of tags (4 min read)
          Pointless (6 min read)
  June 14
    Pointless
      (6 min read)
      The first company I ever started was called Duffy's Computerama, in a town called Paradise, later destroyed in apocalyptic fire. We were mostly under 18, and we were going to change the world. By teaching people how to program computers, in BASIC, and Pascal, and FORTH, at $6 per hour.
      We did not teach many customers. But we did manage to pull off such advertising coups as paying a neighbor kid to play air guitar in front of the former TV repair shop we'd rented next to a pizza parlor. Our attempts to write this off on our taxes resulted in a stern visit from the IRS, who mostly let the partners off with a scary warning about proper bookkeeping. We paid back our loans—we'd borrowed a few thousand from relatives—but to do it, we had to branch out into software development. We did custom applications like general ledger systems for family grocery stores.
      Our next big thing was going to change the world of software development. This was through Generis, a programming language and virtual machine dreamed up by my partner, who was much smarter than me about these things. Picture something similar to the Smalltalk-80 virtual machine, but running on 8-bit hardware like the Apple II and the Atari 800. This was not completely unprecedented. UCSD Pascal ran on a virtual machine on similar hardware. And there was Rosetta Smalltalk, which ran on the Exidy Sorcerer. Generis was designed so objects, including code, could be downloaded over a network, for money, which was pretty ambitious for 1985.
      While we were working on that, we were also planning a modular approach to hardware, everything pluggable. Start with a coprocessor card for the Apple II, cartridges for other platforms, that provides an optimized machine for running our software. Then you make an expansion cage, with standard cards. Pluggable modules everywhere. Leverage that into a new modular computer platform.
      None of it went anywhere. We did not, in fact, change the world.
      So we got real jobs. Mine was with newspaper people, and back then they were real go-getters about truth and justice, and changing the world. And these newspaper people were alternative newspaper people. Which Meant Something, because they were going to fix what was wrong with journalism, which was already going to fix everything wrong with the world.
      The next company I started was in partnership with someone from that alternative newspaper world, who was determined to fix everything that was wrong with news in general. So we were going to change the world through global communication. This took awhile, but eventually, we succeeded in not changing the world.
      So I got another real job, but this time with a company that just made entertainment. Change the world? We just want to entertain you. No big deal, just fun.
      And let me tell you, after decades of trying to change the world, that was pretty refreshing. Nothing mattered! It's OK to not change the world. You don't have to scramble all the time to make rent or payroll, or talk to angel investors, or lawyers, or the grifters that attach themselves like lampreys everywhere, or even be disappointed by Sand Hill Road again. You can just get a paycheck. You can make things, and people will use them. Pretty sweet.
      So I have that same regular job, where I get tasks to work on. My current one is importing some orders from an external source. These orders could have been processed by a system we built in-house several years back. The system which could have handled these orders was built in-house to do specifically what the external source did. For reasons, we used a third party instead of our in-house system. So my task now is to trick our system into thinking it handled those orders in the first place. In other words, redoing the work of a third party that redid our work, because the third party can't do the part that needs to happen now, and we can.
      The system that we built in-house to handle this specific situation was built quickly, but carefully, to support future projects of exactly the same sort. It was for pledge drives, exactly like Kickstarter. This project was built on the fly, with additional layers of flexibility and upsell options and rewards you could shuffle around, requirements that grew weekly, as the pledge drive progressed. In the end, this project required more UI and more options than others of its kind—I personally think it was the first really complicated pledge reward tier management and fulfillment system, but I've never checked.
      The pledge management system we didn't use—which I now have to come up with a process which will trick our system into thinking we did use—was built to support a project that was an extremely important focus for the company. This was making an online multiplayer videogame, similar to World of Warcraft, which was very big at the time. This project did not end up succeeding, but it took a few years to find out.
      Prior to the pledge management system, we'd built a virtual tabletop that would run in a web browser on your iPad. This is a non-trivial undertaking, and it took some time, but we did it. I haven't looked recently, but at the time it had features not shared by others, and direct integration with our customer base and product lines. Pretty sweet.
      That project got shelved, right before final release, in favor of the video game. So we stopped everything, and built that pledge system, which we used once.
      When my son asks me things like, "How many people are ever going to use Blackjack?" I have to be honest. I tell him, I don't think anybody will. I am building it for me.
      I don't tell him that people, if they ever happened to run across it, would probably think it pretty pointless. Nobody needs this thing. There are many, many perfectly good tools that already exist to do these tasks. Bold and italics, really, is that what you're going with here? I don't expect anybody to want to learn how to do things like this. This is literally just for me. And it doesn't even exist. This is literally vaporware, it is just a design so far. I feel bad for wasting peoples' time.
      But I have a picture in my head. I see it. And I can't help but build this thing. It won't change the world—probably—but I can see all the parts, and I know what each does, and how they fit together. I know how to make each part. I've built them all before, some several times. Anything I can't see clearly right now is just because I haven't gotten to that layer yet, this time around.
      And Blackjack is just one of the tools I need first, before I can make the whole thing. I don't have a business plan this time around. I don't have a company. I don't have any customer acquisition plans or hockey stick charts. I am not going to change the world. My job pays the rent. May as well make something.
      I am just going to be over here, making my own thing, with Blackjack. I can't help it. I don't know why.
  June 13
    The typo, which is also made of tags
      (4 min read)
      There is, naturally, a typo in my Blackjack mockup. The code I posted has a flaw, which is that the very bottom node should have been marked with a computer icon. I think. This is the sort of thing that can fluctuate in a mockup, but I am pretty sure by now. This is fantastic for me, because now I can think about that screenshot on a number of levels.
      Horrible, bug-ridden code.
      First, I know precisely how much effort it will take me to fix it. This is one or two clicks. I made an icon for Drummer that just cycles a node's type between a handful of values. It starts off with the angle brackets and the computer, or maybe the other way around. I forget what the rest are because those are the ones I'm using right now. Writing Blackjack code is an extremely fluid experience for me. Yes, this is a mockup. But, the rules are going to be super simple, and I try to be consistent.
      This leads me to the second level I get to think about. This is the code that operates the Blackjack illusion. This can be thought of as a substitution engine. What should it do when it gets to a node that looks like it ought to invoke a substitution, but isn't the right type to invoke a substitution? What do you get? In this case, I believe you should get back literally sub.subs. In other words, exactly what is in the text node. I also believe this should be invalid Blackjack. If you see something italics, you should be able to know for sure that it is a substitution.
      The third level at which we can think about this is, what should my experience be when I do this? I think there should be some sort of indicator. I don't know what, options include color, font, borders, icon.
      I give up portions of my design space pretty carefully. It can take me awhile to settle on the use of something as simple as italics. Because once you've assigned a role to italics, or a highlight color, or even the existence of highlight colors, you need to ensure that everything is consistent. If italics means one thing here, and another thing there, depending on context, now you have to understand the context to interpret what italics means. That diffuses the visual strength and usefulness of the design element, and makes the virtuality you are building that much harder to experience as a real thing.
      The fourth level is, how is this Blackjack outline represented in the browser? Drummer is an application, which runs in a web browser. Which means it is a single URL. The web browser asks the server for the document at this URL. This document is encoded into a text file, consisting of a number of angle brackets, and other symbols. The browser interprets the angle brackets builds a structure called the DOM, which stands for Document Object Model. The elements in this document correspond to everything you can see inside the browser window.
      For an application like Drummer, this is the menus, the icons, the outline, the little wedges and chevrons, the place where you type, the dialog boxes, everything. It's all a document, composed of angle bracket tags. The styling applied to the elements is what makes them look like tabs and menus.
      The OPML document that you are editing in Drummer is a document, too, consisting of those same angle brackets. There is a bunch of JavaScript code that takes those OPML tags, and constructs something that can be stitched into the DOM. This structure looks extremely similar to the outline structure, as it happens. It consists of a hierarchy of tags, each with attributes and values. These are assigned in such a way that the browser will apply rules that positions the elements at the correct place, apply the correct formatting, and decorates them with the appropriate icon.
      So the typo in my Blackjack outline, is represented by a set of tags that look suspiciously like the tags that my Blackjack outline represents. And the user interface that will display the affordance that indicates a typo is driven by attributes attached to those tags, or even more tags arranged around those tags.
      And those tags are being manipulated, rapidly, to maintain the illusion that this document you are viewing in a web browser is actually a responsive application.
  June 12
    The new reallysimple package, as she is spoke
      (5 min read)
      I was curious to look at reallysimple, Dave Winer's new package for working with RSS feeds in JavaScript, so naturally I clicked over to its home on GitHub. I was on my phone, which I usually am when I am sneaking in a bit of research in between time spent with my kid. But I'm used to poking around GitHub repositories on my phone, and finding the stuff I'm interested in. So it's not a terrible experience, usually. Long lines of code require some more horizontal scrolling than I'd like, that sort of thing.
      People will generally use the code in a GitHub repository itself via a package manager of some sort like npm or maven, which is just a thing that ensures you have the latest version of a thing, and all the things that thing depends on. But all that stuff is usually bundled up into an archive format like jar or zip, in the chunks you need for use in whatever development environment you're actually working in. It's not something you typically read.
      The git repository that you browse via the GitHub mobile app or website is basically a hierarchical walk through a file system, with README files given particular prominence. It is an extremely low-level view of the code. You don't get to see the components as they appear presented to the developer in an IDE. You see the raw files that make up the components that the IDE parses and then combines with other data—such as tags, representing key locations in the overall structure, like function declarations—not what the IDE presents in a nicely formatted GUI widget.
      Usually to see that, you need to get a copy of the repository—because GitHub is git, this part is easy—and then open it in exactly the same IDE as that used by the developer of the code. When you're working in a closed loop, like writing software for Apple devices, basically everyone is using the same thing. You use Xcode and the rest of the Apple toolchain, because that's the path of least resistance.
      But you don't have to. You can use basically anything to make anything. You can use an IDE like Xcode or eclipse, or you can work in a text editor, or you can work in a text editor that is an IDE.
      (If you are working in emacs, you are working in a text editor that is an IDE that is a programming language that is a serialization format that is a branch of mathematics that is also a fruit snack, and you may never leave. This is a common problem when making these sorts things, and one I may well fall into with Blackjack.)
      Anyway, I had two realizations about the code. The first realization is, I've seen this type of JavaScript code before. This code is maintained in an outliner, in an OPML file. The OPML file used to edit the JavaScript file is there, and you can look at it in GitHub, but it is presented as a syntax-colored XML file.
      Which, yes, that is what that file is made of. But that is not the contents of the file. What we are seeing there, is the raw encoded form of the file. Which is like looking at a insides of a Word document. Nobody needs to see that.
      So I have spent some time, but not much, looking at the OPML source for these things. Mostly I've focused on the JavaScript, because that's the code that runs.
      Today, I realized, I may not have the actual application used to work with this OPML outline, which creates this JavaScript code. I do not have the code that will turn this OPML outline into JavaScript code. But I do have Drummer. And Drummer will let me view this outline beautifully.
      What the reallysimple package looks like in Drummer.
      So my first realization is, the best way for me to view this repository is to just use File → Open URL... and paste in https://raw.githubusercontent.com/scripting/reallysimple/main/source.opml
      I am excited about this, because it means that I can easily navigate the whole reallysimple repository in a single, nice, collapsible structure. To view reallysimple.js itself, I just expand a couple nodes, and then use the pin icon to focus the view on just that file. From there, I can use Drummer's outliner commands to poke around the JavaScript code, expanding and collapsing sections as I like.
      The other files in the repository are represented in the same outline, as well. The README and worknotes, everything. Very handy. You can see how and why the code is what it is. This is the kind of insight into a codebase that you can often only get if you are on Slack with the developer. Or have the time to spend, laboriously comparing diffs, trying to determine why something changed—git will tell you what, but it can't tell you why.
      And that leads me to the second realization. This realization is that the reallysimple package is an expression of taste. You can see this at work in the above screenshot, actually. Taste is not the same as skill, virtuosity, cleverness, or genius. A great artist, working in any medium, needs all those things, and more. But what they also need a great deal of, is taste.
      When the sculptor says, "I just carve away all the parts that aren't the statue," they are making a statement about more than simple removal of physical material. They are carving away all the possibilities that aren't true to the nature of the truth they are telling. They are saying, all those things, which I have removed, are not essential to represent that which I am conveying. You don't need this, in other words. What you need instead, is just these parts, in just this way.
      And that's exactly what the reallysimple package is. If you dig down, what it does, literally, is you give it a file. It gives you back the essence of that file, as processed by an artist. You get back a filtered, extracted, clarified, hand-selected, fine-tuned, just-what-you-need, curated view of what you gave it.
      Now, the interesting thing about software, as opposed to statues, is this. When you see a work of art in a museum, you see that work. You get the benefit of the artist's transformative ability, earned through years of repeated application and refinement of judgement, as applied to that concept, in that medium, in that particular work. This can be an astonishing experience. When an artist works with software, each work can apply that taste to create new works—each of which can also be an astonishing experience.
  June 11
    Using Blackjack to insert Drumkit docs
      (3 min read)
      One of the things I want Blackjack to be good at is distinguishing levels. Another is making things as clear as possible. I want it to be a tool for writing tools for direct manipulation of outlines. So what might DocServer Lookup look like in Blackjack?
      A Blackjack version of Insert Drumkit docs for verb.
      I've previously called Blackjack's bold and italics references a sort of magic trick, and here we can see another example. Bolded components can have more than one argument. They're unnamed, and the unformatted text surrounding each is treated as delimiters.
      In this case, the first argument to List is the list we want to iterate over. The second argument is how we want to refer to that list within the descendent nodes. List of section.subs named chunks could be written as List the section.subs but refer to them as chunks. This is sugar so we don't need a Settings section for the List, with an entry for chunks, defining it as section.subs.
      (The multiple-argument-inline thing has come and gone a few times in the Blackjack design, so don't be surprised if it gets shoved back down into that Settings node later.)
      The reason for this specific piece of sugar is actually right here. We will be iterating over multiple levels of an outline all the time in Blackjack, and these levels are all going to be named "subs". This is going to be ridiculously hard to keep straight, so the easier it is to give them different names, the better.
      You can see that by the time we've gotten around to calling these things chunks, we no longer care how many levels there are. So we just hand the rest off to the OPML component.
      The most deeply nested List demonstrates that at the leaf level–of our interest, there may be many levels below this—we may as well use subs instead of renaming them chunks or something.
  June 10
    A closer look at DocServer Lookup
      (7 min read)
      There are two broad categories of applications in the world—work with me here—consumer apps, and pro apps. Apple has a couple places where they have entries in both categories. GarageBand is an aptly-named consumer app for making music. Logic Pro is a mostly aptly-named professional app for making music.
      The number of controls available, and complexity of the options, can increase enormously when you make the jump from consumer to pro. Logic Pro, in fact, has an intro mode that hides much of its complexity, specifically pitched to GarageBand users. Even then, it's still more complicated than GarageBand. You would not believe how complicated it can be to make something like a pop song.
      And Logic Pro, it turns out, has been around long enough to have developed entire layers of features, which can only be enabled via additional preferences beyond "no, really put me into Pro mode". The manual says things like, “The Environment is a legacy feature and included for compatibility with projects from older versions of Logic Pro.” But fancy newer features are often built on top of clunky legacy things, so I wouldn't be surprised to discover that you couldn't easily excise the Environment from Logic's codebase.
      Pro apps are generally scriptable, and tend to support a LOT of ways to get data in and out. And they have a lot of controls. These are all attributes shared with test equipment, actually.
      I think of Drummer as a pro app for working with structured network data. Its main user experience is an outline, and it comes with a default set of tools for data lookup and outline manipulation. There is a default focus on blogging, but because Drummer is scriptable, you can add commands to assist in other kinds of data lookup and outline manipulation.
      DocServer Lookup is an example of the kind of customization you can add to Drummer. I wrote it to help me look up the documentation for Drumkit verbs. You highlight something in your code, click the ? (that's a bold question mark) icon, and it inserts any documentation it finds as a comment into your outline.
      DocServer Lookup in action.
      This is a typical feature of an IDE—"integrated development environment", another kind of pro app for making apps—and it's the sort of thing that I missed when working in Drummer. Other typical features include refactoring support, which requires that the IDE be able to parse the structure of the code you're making.
      Rather than simply letting you edit and move text, and look up documentation, with refactoring support, the IDE can also do things like extract an expression into a variable. Or rename things that have the old spelling scattered across hundreds of files, in a single step. You can add and remove arguments from functions, move methods around between classes, extract new classes, that sort of thing. There are a lot of things that we do all the time, and eventually, we build tools to automate them.
      The Drumkit outline for DocServer Lookup.
      DocServer Lookup is 343 lines of OPML, and all the complexity is hidden behind those collapsed function nodes at the bottom. None of this is Blackjack, this is just how my Drumkit code looks in Drummer. The bolded parts such as Get the selected text are just standard JavaScript line comments, prefixed with double-slashes, and then bold tags applied inline. The nodes with chevrons are also comments.
      The code is basically two parts, setup and execution. Setup happens lazily during execution, and involves fetching the OPML documentation file that DocServer uses, and extracting the text we need. When you click the question mark icon, we extract the selected text, and attempt to find it in the documentation we extracted. If we find it, we insert it into the outline, with some formatting applied.
      Finding the documentation, and inserting it into the outline.
      The InsertDrumkitVerbDocs() function is pretty straightforward. Given a searchterm, we find it in the data provided by GetDrumkitVerbDocs(), and then use OpInsertExtractedOpmlSection() to insert the results into the outline.
      It's not as clear as it could be, though. For example, to understand why searchcat is constructed the way it is, you need to be familiar with the data structure returned by GetDrumkitVerbDocs(). This is not unusual in programming, and providing information about things like that via inspectors, hover panels, etc., is part of what an IDE does. Because all this code is an outline, it's easy enough to locate other things for now, even without those tools.
      Inserting the documentation extracted from OPML into the outline.
      Drummer provides some standard outline manipulation verbs, which I believe probably date back to the Frontier days. These allow you to do things like traverse nodes, collapse and expand them, insert nodes. DocServer Lookup uses these verbs to insert the documentation extracted from OPML into the current outline. There are a few things about this code that I'd like to point out.
      First, I find it kind of hard to understand what's going on. It operates by maintaining a cursor, and traversing nodes in the outline. So you have to follow the steps to see what it's actually doing. Without the detailed documentation at the top of the function, it would take me some time to read through it and figure out what the result should look like.
      The fact that it's recursive just makes it worse—this function calls itself, with different arguments, repeatedly. And one of the arguments is the direction we're traversing. We switch back and forth between right and down. So you have to keep straight which time through this code you're thinking about.
      The other main thing I wanted to draw attention to here are the lines that apply the bold and italics formatting to the inserted nodes. You can see a couple commented-out lines, which use op.bold() and op.italic() verbs to apply the formatting. They're comments because I couldn't get them working, and just added the formatting manually, via HTML b and i tags.
      What I want is for the label to be constructed from some bold or italics tags, and the text. So the code actually uses a quoted string constant. This is a b tag, in angle brackets, by typing lessthan-b-greaterthan. (On my keyboard, lessthan is typed by shift-comma, and greaterthan by typing shift-period, but spelling it out is easier to read.)
      Now, what's going to happen is, Drummer is going to see that, and apply the formatting inline. This is how I make my bold and italicized comments in Drumkit—they're just angle bracket tags inserted directly into the code.
      But here I don't want the code itself bolded and italicized. I want what gets inserted to be formatted. There is a way around this. What you do is you escape the enclosing angle brackets around the b tag, by typing ampersand-lt-semicolon-b-ampersand-gt-semicolon. This provides the clue that we want to encode those tags, rather than displaying them inline. When you do it this way, you get to see the enclosing angle brackets.
      But take a closer look at those lines. They are bolded and italicized in the code itself! This confused me for some time, because I remembered typing them with the ampersand-lt-etc encoding. Then I'd go back later, and the code would be bolded and italicized. I'd fix it, and later it would be back to inline bold and italics. This is probably due to a bug in Concord, Drummer's underlying outliner framework. I can't fix that just yet, so eventually I punted and just left the formatting as is.
      This is a good example of why there are no visible angle brackets allowed in a Blackjack outline. Maybe if I ban them entirely, I can escape some of these problems.
  June 8
    The rules for Blackjack
      (2 min read)
      I don't know all the rules yet, but there are some that I do know. Here's what I think I know so far about the syntax.
      A Blackjack script is a normal OPML outline.
      There are no hidden attributes in a Blackjack outline which you'd need an inspector to see.
      The only HTML tags allowed in a Blackjack outline are b and i, used for applying bold and italic formatting. These are applied by ⌘B and ⌘I.
      This bold and italic is how you create references and definitions in Blackjack.
      There are no angle brackets in a Blackjack outline. Use Blackjack's angle bracket node type to generate tags surrounded by angle brackets.
      Nodes with the angle brackets icon have the OPML type attribute set to "html".
      The first string determines the tag to be inserted. The remainder of the string determines the attributes.
      Angle bracket nodes with descendents get rendered as container tags, surrounding the nested content provided by the descendent nodes.
      Italics references get replaced with their definition, like a variable.
      Components determine how they handle descendent nodes.
      Nodes with the computer icon have the OPML type attribute set to "code". These nodes indicate Drumkit or a component reference.
      A bolded name with a dot indicates a definition. You type the dot yourself with option-8.
      Bolded references look like they have fancy AppleScript-type syntax, but that is an illusion. They actually follow a simple pattern: Bold part, unformatted stuff, italics reference.
      The bold part is the name of the component. The unformatted stuff is skipped. The italics reference is replaced.
      The italics reference can be thought of as the default argument to the component.
      A component can have more arguments. They are specified via the Settings component. These can have defaults and cascading overrides based on context.
      Because Blackjack skips the unformatted stuff in between the bolded component name and the italics argument, you can put whatever sounds good there. "List of artists" could be written as "List consisting of those things which we named artists".
      Those List plurals are another illusion. By default, the iterator in a list can be referenced by item.
      You can also reference the iterator by the name of the list property, by converting any trailing "ies" into "y", or dropping any trailing "s". This gets you from artists to artist, and from directories to directory. For everything else, there is item.
    Blackjack vortex
      (2 min read)
      Naturally, once you start thinking about level shifting, and code that generates code, the next step is self-replicating code. I hadn't thought previously about what that might look like in Blackjack, so I was curious to see. This is what I came up with this morning.
      First attempt at self-replicating code in Blackjack.
      I think this might do the trick, but I need to step through it carefully to see if it will. It probably won't work—the first try at something like this never does. (At first glance, I can already see that I forgot to bold some of the String references, which means I probably need to construct another string somewhere.)
      But it's fun to think about, and apparently, this is what I do for fun.
    A bug in the happy place
      The previous mockup has a bug. You still have to italicize the name of the json object being defined. This is basically the same bug as having to manually apply the bold formatting to declare the component reference, which means I was looking right at it and didn't see it.
      This is how writing software goes. You feel like a genius one day, and the next you can see just how blind you were.
      The reason I didn't see it, of course, is because the symbol I wanted to be italics in the generated output was italics in the code that generated that output. This is a great example of the kind of level shifting that is easy to lose track of.
      Anyway, the fix is easy:
      Italicizing the name in the generated Blackjack.
  June 7

    I am totally killing it
    I am totally killing it right now. Somehow.

      (2 min read)
      I am totally killing it right now. There is no stopping me. I am completely ruling. This cannot be denied.
      This is my moment in the sun, and I am going to enjoy. Bring out the drinks with the little umbrellas, because I am celebrating.
      My Zoom background is me.
      When I add up all the ways that I am completely and totally killing it at the moment, I will not be prevented from using all the digits. Every single number, even 4, will be mine to use as I please. I may even use letters of the alphabet as numbers. That is how much I am killing it. So much, I need alphabet numbers.
      The dance I am doing, here in my chair, at my desk, in front of my keyboard, looking at Slack, is epic. You need to know this. That is how much I am killing it right now.
      Everything is aligned exactly right. Everything is coming up me, me, me. My life is gold, my lines are tight, my flow is sweet, my aim is true, and you just know I am totally killing it right now. Kanye is coming to me looking for tips on how to rule like me.
      This is what I am saying. This is how large I am living. I am killing it so good, famous people are paying me cash money.
      When they make a list of all the people in the world who are killing it right now, that is where you will find my name, at the top, impressed right into thick paper, with a really heavy stamp, so you can feel just how impressive I am right now.
      That is the impression you will have, of me: There is someone who is absolutely killing it.
      Even though I am actually unsure of what it actually is, I am still killing it. Whatever it is.
      I know it's there. It's got to be there. It's right there. Right?
      Is it an animal? Maybe. It could be something really scary. Like a really angry ghost. Or a moldy Kermit. Possibly a space alien. What is it? I am not sure.
      It ate the cat yesterday.
      I don't know how to hurt it, if it can even be damaged. Maybe it just sits there, soaking up damage because it has like a million HP. What then? I do not know. And what if there are tentacles, like a lot of tentacles? I am not sure about tentacles, if they are sharp. They can be sharp, right?
      What if every time it eats another cat, it grows another tentacle? And then, like, barfs up the cat, and eats it again. That could be a lot of tentacles.
      I mean, the cat is gone. I am pretty sure about this. Maybe.
      I know only one thing. There is only one fact, which cannot be denied:
      I am totally killing it.
      Somehow.
    Blackjack and the happy place
      (4 min read)
      Apparently I completely forgot how Blackjack even works or what it is for. The previous mockup should obviously look like this:
      A much better component that fetches json, then builds a component to represent that data structure.
      I had to invent the String component, but the hardest part about that was naming it. I mean, obviously it constructs a string based on its descendent nodes. But it could be called StringBuilder, or Concat, or Cat, or S. Other candidates include += and worse. Because we don't really care what it's called, we just want the string, maybe it should just be _ (that's a bold underscore).
      More in keeping with Blackjack's typographical theme would be to use … (that's a bold ellipsis, which is different from three bolded periods). For now, I think String will do.
      The important thing for me is that I didn't have to invent anything really new to solve this meta-level-escaping problem. String is a bog-standard Blackjack component, it has child nodes, it does something with them, it resolves a setting when asked. It assembles the string using normal Blackjack node types. There is no new "meta" node type. There's no new generics syntax. We just need something wrapped in a b tag? No problem. This is Blackjack's happy place.
      The part that inserts the outline nodes really drives home just how I'd forgotten what Blackjack actually even is. Blackjack is OPML. Sometimes I think about the outline structure represented by a Blackjack outline separately, like a mathematical object. That's what got me confused here, which is a perfect example of what I mean when I say it is tricky to think about such things due to all these mixed level references.
      What we need to generate, when we are generating Blackjack, is just OPML. We don't need to generate the structure first, and then render that into OPML. A Blackjack script is not a serialization of some other structure. (Except where it really is, which is everywhere, but that's just part of the magic trick, the sham, the virtuality.) Blackjack will have a runtime context that it builds, updates, and carries around, as it does its thing, but a Blackjack script is itself OPML.
      This is tricky for me to remember, because this is not how, say, Java works. A Java program gets compiled from text files. These files have ridiculous numbers of rules about how they are formatted. That's what the compiler does. It uses all those rules to build up a structure. If you omit a single curly brace, the entire structure is completely invalid. Nothing can be done with the result. There is no result! That virtual structure is the only structure that matters. If you can't properly construct the entire thing, it doesn't exist. It is the most precarious house of cards you can possibly imagine.
      Once you get it all compiled, and it actually exists, you can do all sorts of things with it, besides just running the code. You can use reflection, to poke around that structure, and see what's actually inside. I used this when I generated pictures of the Ent. The text files were too hard to understand, even though they were—eventually—valid Java. But I could write code that would query each object, discover what methods and properties it had, and follow the links. From there, I could make graphs, color and style the nodes and lines, and move things around.
      But if you can't compile it, you can't run it, which means you can't tell what it's going to do at runtime, which means, you can't get the reflection working. All the structure in a Java program comes from that very first step. There is nothing, if it can't be compiled. You have zero, you can't reason about it in any fashion. When you can't make use of that Java file because of that one missing brace, that brace is missing because you have to put it there by hand.
      Blackjack is different. Yes, you can break a Blackjack file by making invalid OPML. But that is not making a bad Blackjack file, that is making a bad OPML file. A bad OPML file is due to a bug in the outliner, not because you were editing an OPML file by hand.
      Parsing a Blackjack file, and being able to make use of its structure, can happen on a different level, than we do with things like Java.
      When you're working in an outliner, you can't forget to close the tag that ensures you have made a proper OPML node. The outliner takes care of that structure for you.
    Builds versus does
      (5 min read)
      Programming languages are not designed to actually do anything useful. They're designed to make it easier to make things. Those things then are what actually does those useful things. That's where all the sugar comes in. When you are working with computers, you are working with repetition. You are building a thing which will do something—a machine—and we build machines to do things over and over again. This is why programming languages all have loops and functions. The code will loop over a list of tasks, until some limit is reached. You can break your code up into smaller chunks, which you can use in more than one way.
      (I'm using the term "function" pretty loosely here, in a way that encompasses modules, subroutines, packages, closures and FORTH words. Different languages call them by different names, and these things do vary. A closure is not actually the same as a package. But it's a way of modularizing your code. In Blackjack, the modular unit is mostly the bolded component reference. But because Blackjack is an outline, you can also think of nodes as units of abstraction, and you can shuffle things around a bit more fluidly than in some languages.)
      In addition to the repetition that the machine goes through as it functions, software development itself is repetitive. You are making similar things, repeatedly. This why we keep getting new programming languages. After awhile, you think to yourself, There must be a better way, and after some delightful time spent thinking and typing, voila, there it is! So programming languages often provide specific support for making things that make things. This can be hard to wrap your head around, because when you are looking at this kind of code, you have to keep two things in mind simultaneously. There is the thing the code builds, and then there is the thing that built code eventually does.
      FORTH is often implemented as a threaded, interpreted language. In these designs, your code is built up from words. A word is just a name, a symbol, to which we attach its definition. Which is a list of… other words. To run your program, FORTH looks up the word, then steps through its list of words, following the thread through each one's definition. Eventually we end up with a word that's been defined in terms of assembly language instructions, so we hand those to the CPU, and it executes them. When the assembly language-defined word is done, we go back to the others, and continue following the thread. Eventually we reach a word that says we're done, and FORTH goes back to waiting for something to do.
      The whole process is pretty straightforward, and has a delightful knocking-down-the-dominoes kind of feel to it. It just goes and goes until it stops. The tricky part, of course, is that FORTH uses the exact same process to build the list of words which make up the definition of the word you're writing. Now, you need to be able to tell FORTH to switch back and forth between modes, and say "now we are defining how you can build a new word" and "now we are defining how you can say what that new word does". Naturally, because this is FORTH, these words usually look like line noise, and the whole thing is quite unreadable.
      In Blackjack, one of the things you'll be doing all the time is mapping external data sources into a form you can use. In the Art Show mockup, we are fetching and parsing chunks of json that describe pictures. This is easy to do in a single line of Drumkit, but bundling this behavior along with documentation and sample data will make it easier to revisit this code in the future. So we use the Create from json component to keep it together.
      A portion of Create from json artShowEntry.
      It's useful to have, but kind of a pain to build. I made this one manually, looking at some JSON in one window, and Drummer in the other. Lot of copy-pasting. This is repetitive work, and translating JSON into an outline structure is what Blackjack is supposed to do. Can we use Blackjack to modify a Blackjack outline? Sure, that's one of my goals. It kind of makes my head spin to think about the details, though. Yesterday I decided to find out what it might be like to write one.
      A component that fetches some json, and then builds a component to represent that data structure.
      The Insert outline node components probably deserve a special icon, just like the angle bracket icon that Blackjack uses to indicate HTML nodes. The bold will do for now, though. Instead of HTML, this component will use op.insert verbs to add nodes to the current outline.
      Like most meta-programming code, it ends up pretty short. And kind of cryptic. But it didn't take me long to write up, and it makes sense to me when I look at it the next day. That's good, because due to working at the builds and does levels simultaneously, this kind of code can be really hard to reason about.
      Mockups are all about handwaving away the details you don't want to deal with just yet. The biggest hole here is that after you run this code, you'll need to select the "Create from json" text in the newly added portion of the outline, and add the bold formatting yourself to turn it into an actual component reference.
      It could be really confusing just what bolded items are actually just definitions within this method, and which bolded items are actual references that need resolving while this code is running. So we need a way to apply that bold formatting at runtime. Perhaps the definition of createNodeText will end up being something more like this: format.bold("Create from json") + " " + jsonObjectName.
      This is the basic builds versus does issue in Blackjack. It's a fundamental feature of anything that does what Blackjack is intended to do. It's the first step down a long, strange, path. I am curious to see how I'll end up making it happen.
  June 6
    Where does the sugar go?
      (2 min read)
      Blackjack is all about mapping things from one context to another. How do we get those things into a context in the first place? Because Blackjack runs inside Drummer, we have all the Drumkit verbs we need for this. We can read and parse OPML and json. We can fetch files via HTTP and tweets from Twitter. And for the Art Show mockup, we can get them from GitHub repositories.
      Blackjack is just a bunch of sugar wrapped around outlines and Drumkit, which is sugar wrapped around JavaScript, which is sugar applied liberally to moving bits around. Writing software is often a process of figuring out just where to add the sugar. It makes it sweeter. It hides some of the complexity. Hopefully, it makes it easier to read, write and reason about what you're doing. But it can get in the way.
      The main unit of abstraction in Blackjack are those bolded component references. They act kind of like functions. They represent little chunks of reusable content transformation. While I'm working on the mockup, some pieces wobble back and forth between being a bolded reference, and just a Drumkit verb.
      Resolving Art Show settings via Drummer's gitHub verbs.
      Here I've expanded the outline so we can see how artistFolders gets resolved. It's just a line of Drumkit. I've also expanded artShowEntry, and we can see it's also a line of Drumkit. They each call verbs in Drummer's gitHub family.
      Below, we can see a use of Create GitHub file. This is mostly a wrapper around another gitHub verb.
      My mockups often include the same concept rendered in more than one way, until I settle on an approach. Here, the question might be, do I make it a bolded component, or should it just be a Drumkit call? Sometimes it's good to see both ways on the screen at once.
      That base64.decode wrapper around gitHub.download definitely rates some sugar. It makes sense to promote it to a bolded component.
      But what about that gitHub.getDirectory call? We don't need to unwrap anything, we can use the data structure we get from it, as is. Any Blackjack-aware outliner should probably have a command to extract a Drumkit call into a bolded component, for when I change my mind.
  June 5
    Using Blackjack to make an art show
      (5 min read)
      The best software is like a magic trick. One of the original builders of the Ent told me once that building it inspired him to adopt the creed: "good object-oriented design means doing almost nothing in just enough places."
      Eventually, I will connect up enough little parts, and my Blackjack mockup outline will suddenly shudder into life. At that point, it's no longer a mockup. Well, the parts I've wired up, at least. What will that mockup do, anyway? You need a proof-of-concept for a project like this. Actually, you need a lot, because you want to cover a wide variety of use cases.
      One of mine is implementing all the Bootstrap demonstration templates. I picked them because they're pretty, and I've used Bootstrap before. But what content should I run through the templates?
      Why not great art? On Twitter, there are people who post pictures of art, like the stuff you see in museums. Hopper, Picasso, that sort of thing. Dave Winer has a curated list of accounts to follow, and his artDownloader project gathers all that art in one place, complete with json metadata. Fortunately for Blackjack, that place is a GitHub repository.
      Here's a look at how we might use Blackjack to turn that collection of jpeg and json files into a website. Let's call it Art Show. The main page will list all the artists. Clicking on at artist will take you to a gallery page for that artist, and individual images will have detail pages as well.
      We'll use a Bootstrap image gallery template for both the individual artist pages, as well as the main page. We'll show the most recent picture we've found for an artist to represent them on the main page.
      We'll be using GitHub Pages to host the website that Blackjack builds. It's perfect for this, because all the jpegs are already in a GitHub repository. This mockup will assume that we've made our own copy of that repository, and have properly configured it to act as the document root for a GitHub site. Each HTML file we generate gets uploaded to GitHub, and GitHub Pages will be our web server.
      In the artDownloader repository, there is a json file at a location like /data/json/artistrothko/E--e9J_X0AQV64W.json which describes each file in the /data/images directory. It contains metadata about the image and the tweet that originally posted it.
      The steps to turn a collection of json and jpeg files into a website.
      The steps you'd take to turn those json files into a website are pretty straightforward. You iterate over the artist directories, and in each directory, you gather up all the json files, extracting the data you need from each. Then, you run that data through a template, which creates an HTML file for each image, one for each artist, and one for the overall website. Each file then gets uploaded to GitHub, where GitHub Pages acts as our web server.
      Some of the settings for Art Show.
      Blackjack works by iterating over the nodes in a template outline. It maintains the current context, which is how italicized references are resolved. Context is generally modified via the Settings component.
      The context cascades down through nodes as we step through the outline. Each node can modify the context for the nodes which follow. Nodes which contain other nodes create local bubble contexts that get discarded. In a loop, each iteration has its own context, with new values.
      In this case, Art Show has the typical settings you might expect to configure a process like this. Once we've defined something like inputPath, nodes further down the list, or more deeply nested, have access to that value. We can also see that we've defined something called artistFolders, but the implementation is collapsed for now. Below, we iterate over a List of those.
      Extracting json data and remapping with Drumkit.
      Most of the work involved here is just taking values from the json, doing something with them, and pushing them into the appropriate places in an HTML page. I haven't decided just what exactly Create from json does besides parse json into a JavaScript object, and then give it a name we can refer to later. It could be replaced by a line of Drumkit.
      Those Example and Description nodes don't actually do anything—they're mostly there to serve as documentation. Possibly something to do with automated testing, or previews. Having that kind of example usage right at hand, I've found, is really useful when understanding what code does. Or at least what you thought the code was supposed to do when you wrote it.
      The picture object being created here is just another JavaScript object, like the one we got directly from json. It's just been remapped a bit, with more useful properties for our purpose here. It's a convenience, just like anything else here.
      This whole structure could be done in any of a million other templating languages. Those Settings things look suspiciously like they could just be variable declarations. Create GitHub file is just sugar around a Drumkit verb. After awhile, once you look hard enough, you see the same thing everywhere, and your job is to translate that same thing, which doesn't exist, into one form or another, which does.
      Sometimes we do that our entire lives, over and over, revisiting concepts until we run out of time. Someone else will take over after us. These things probably exist outside time anyway, like math. They're obvious, and just take putting together, once you can see how the pieces fit.
  June 3
    The ugliest thing I've ever made
      (2 min read)
      I've written that Blackjack's form of markup is essentially invisible. This is, of course, a total sham. It is not. Blackjack is actually one of the ugliest templating languages ever designed.
      Here's an example implementation of an image in Blackjack.
      This is what Blackjack looks like when you're working with it. The bold and italics parts are the things that are being manipulated by Blackjack. The remaining tags are just what's in the Bootstrap demo for displaying an image on a card. If this were a contrived demo it probably wouldn't have as much styling. But real world templates look like this, they're full of crazy markup.
      My goal for Blackjack is to let you see two things at once—the Blackjack part, and that part you are generating. In this example, that's the Bootstrap part. Ideally, your perspective can flip back and forth, like looking at an optical illusion.
      Here's what that Blackjack file really looks like.
      I think I can state confidently that this looks like total crap. This template is nearly impossible to read and understand. Nobody would ever want to work with a raw Blackjack file. All those encoding and escaping issues I've written about? They are all right there, laid bare.
      This goes against every one of my instincts when designing something. I care about how my code looks, how clean my data structure, how properly factored-out everything is. I care a lot.
      And Blackjack.opml is one of the ugliest things I've ever created, under the covers.
      But, it's just OPML. So I can use literally any OPML editor in the world to edit a Blackjack file.
      The outliner doesn't even have to support displaying the bold and italics inline. That's the visual equivalent of syntactic sugar for Blackjack.
      Here's what that Blackjack file looks like without inline formatting.
      This is not something I'd want to work with every day, but it's livable. The only things you have to squint to see are the bold and italics tags.
      If I were going to apply more visual styling to how Blackjack templates look in Drummer, I'd probably experiment with putting all the non-Blackjack parts at 80 percent grey, except for the node being edited. This is the sort of idea that gets sorted out through mockups. (One day, you connect up that final step, and your mockup is now an actual working thing, and you are done!)
  June 2
    The Contraption
      (4 min read �� Illustration by DALL-E)
      The Contraption is a monstrous beast of a thing. Forty years in the making. Built by a series of devoted madmen who believed they understood the future -- and sought to shape the world into a utopia.
      They kept its secrets for decades, knowing its power, and hoping to profit when it would be finally, triumphally, unleashed on an unsuspecting humanity.
      But changing the world is hard. And the task they set for themselves may have been, in the end, quite impossible.
      So the years passed, and the madmen built, and built, and built. They tore it down completely and rebuilt from the ground up time after time. This one will be so much more powerful than the last incarnation! We'd be fools not to pursue this path.
      And so they discarded work as they proceeded, three years here, five years there.
      Near the end of its chaotic pre-life (two-steps-forward, three-steps-backward, four-steps-forward the entire way), the Contraption was nearly complete. Given a simple task, it could mostly do it.
      The madmen believed that with just a few more months of preparation, it would be ready to unveil.
      All they needed was time. And time is money. And they didn't have it. All they had was a nearly-working world-changing thing and the expertise to make it really work -- if they only had the time.
      Then they got some money. Actually quite a bit of money. A golden opportunity! We can finally realize our vision!
      As is often the case, the money probably caused more problems than it solved.
      All the caretakers of the Contraption were true believers. But as true believers of good faith are wont to do, some disagreed with their peers.
      We can use this money to finish the Contraption once and for all! was pitted against If we rebuild it just one last time, it will be more powerful than we ever imagined. We'd be fools not to pursue this path.
      The high priest, the original visionary, the voice howling in the wilderness, the genius who insisted that the Contraption could be made to work, the one who convinced the true believers of the rightness of their quest and what it would mean for the world at large... well, he tried to rein them all in, tried to be the voice of sanity and reason, and provide the guidance they desperately needed at that late hour.
      I think you can guess which path they chose, given that the world hasn't been changed, and the name of the Contraption is not a household word.
      The latest model of the Contraption, the one that could mostly do it, was scrapped.
      Work began on a new one.
      The new design was bold. Breathtaking in scope, actually, even compared to previous attempts, the ones that would change the world. This truly was an amazing undertaking.
      The madmen built. They tore down and built again. They built with a frenzy.
      Throughout the history of the Contraption, they had made new names for the things they were building because they were things never seen before in the world. Enfilades. Tumblers. Disps. Wids. Crums.
      But now, they made new names and discarded them at a furious pace. Grabbers, Orgls, IObjects, Waldoes and many others existed, but only for a very brief time. They created Snarfs, Butterflies, Shepherds, Abrahams, Fossils, Turtles, Pumpkins and Flocks. They built Fluids and Emulsions, TrailBlazers and Canopies, BertCrums and CanopyCrums.
      They invented their own language -- beyond the Crums and Snarfs and whatnot -- they actually created their own language, their own grammar, their own vocabulary, to describe their creation, because it could not be properly bound using any current language. Think of a vision so powerful it could not be expressed in English, or French, or Latin, or Swahili.
      Their project required crazy things, so they did those things, because they were necessary.
      The money ran out before they finished.
      The faithful left because they had to. The visionary moved on.
      Decades ago the Contraption was abandoned, half-built, its parts scattered across the floor in an abandoned warehouse, gathering dust.
      The end.
      Or not the end. In the waning days of the previous century, the visionary and the remaining faithful madmen agreed to set the Contraption free. They renounced their decades of secrecy, let go of their dreams of making a new world out of whole cloth, and gave their secrets to anyone who would listen.
      There was a brief flurry of attention, followed by a years-long lull. The Contraption was in pieces and didn't work and was only described in that language only spoken by the madmen themselves. No one could understand quite what was being described. You could kind of make it out, if you stood 30,000 feet above it. But the details were hopelessly complicated.
      Many people tried, but failed, to do anything useful with the detritus of the thing.
      Then one person actually managed to translate what had been written into a modern language. The Contraption wouldn't do anything. It couldn't even be assembled from the pieces into something that would do anything. But at least those who had eyes to see could read what was going on.
      More years intervened, with no one really making anything of the Contraption, even in its newly translated form.
      That's when I got started on the Loaf Question.
May 2022
  May 31

    The Loaf Question
    Some call it the most famous vaporware in the world. Never before seen pictures of legendary ent, the data structure at the heart of Xanadu.

      (5 min read)
      I generated these images from a data structure known as the Ent.
      The simplest possible structure for the ent. It is storing the word "foo".
      Created for Ted Nelson's Xanadu® project between 1988 and 1992, this "walking tree of long memory" was the culmination of a decades-long effort to store literally every version of everything, and keep track of who owned the copyright, even for derivative, transformative works.
      A work, created as "Howdy doody", has been revised to say "Good bye".
      Two works. One of the works refers to the other.
      In the world envisioned here, if you created a meme that millions used, every one of those memes would point back to yours. When someone makes a T-shirt of your meme, you would get paid. Automatically. This is kind of like the world described by NFTs, except the ones getting paid are the creators, rather than the grifters, or the speculators.
      The same two works, from the other work's perspective.
      Transclusion. DspLoafs indicate a displacement applied to a range of text.
      The BeGrandMap, and the only actual Ent.
      The project has been called the most famous vaporware in the world. It never shipped. Autodesk poured a bunch of money into it, and then shelved it. The design for the ent itself was a closely held trade secret, and legendarily difficult to comprehend.
      Exercising a transclusion bug.
      A compiler for X++, the Smalltalk-to-C++ variant in which the code was originally written, no longer exists, to my knowledge. But it has been translated, mechanically and by hand, into Java.
      Range transclusion. Loaf branches indicate distinctions between regions in the coordinate space.
      See here for more details about these images, or read more about the history of the contraption.
    How do you deal with an infinite outline?
      (6 min read)
      Obviously, there is no such thing as an infinite outline. There exists nowhere a single stream of bytes which you can say "this is my outline", anyway. Those bytes are not in a single straight line, they are in rows and columns, they've been paged in and out, and banked and switched, and assigned to sectors, and written in multiple places scattered all to here and back. This is any file on your computer. Anything synchronized across devices, even more so. When you open a plain old text file, and scroll through it, you're experiencing what Ted Nelson dubbed a "virtuality". It's all a sham, a show, a picture, pretend, magic. It acts like the text is all there, scrolling in front of us, so we believe it. It feels real. But behind the scenes there are no letters sliding anywhere. It's all far more complicated than that.
      But I want an infinite outline, and I want it synchronized everywhere, and I want a very special kind of time machine. Each requirement implies something.
      First, this could be a pretty big file, eventually. For now, think of it containing just metadata, and text. Images and PDFs—what we like to call "blobs"—would be stored elsewhere. This is still just a big OPML file. I am not interested in binhexing or uuencoding or whatever the latest way to encode binary data in text, that is not what I want to use OPML for. But my mental model is, this is every OPML file I have, in one.
      Second, the file has to exist somewhere all my devices can get to it, which means the cloud, which means we'll be loading and saving this file all the time.
      So clearly, this probably shouldn't just be one big OPML file that gets uploaded and downloaded everywhere. For one, that's expensive in terms of bandwidth. For most situations these days that probably doesn't matter that much, but there are still mobile devices and limited resources. So we will need to break it up into smaller chunks. That's fine, one of my goals is to have various portions of this outline have a permanent live instant export to individual files out in the local file system, and we need files anyway, so we can probably get away with virtualizing any part of the outline that is a straight-up one-to-one mapping to a file. We'll let the operating system notify us of any changes to the file made externally to our process, so we can keep this portion of the overall infinite outline properly updated.
      That kind of solves part of the size problem, because you've just sliced those parts out of the main outline. You're just putting a reference to that file into the outline, so we know that entire portion of the outline hasn't changed (unless it just has, of course), so we don't have to bother uploading that part of the outline. We can do a similar thing with individual Drummer files. There's my infinite outline, and parts of it are Drummer files, and parts are individual files on my hard drive. The canonical version has to be in the cloud, just like Drummer files, because it has to be somewhere everything else can talk to.
      My third requirement is, I want a very special kind of time machine. I want to be able to go back and forth in time for this outline. You can do that by just saving a whole separate copy each time there's a difference, instead of overwriting the same file each time. This is actually how Roady works. Once a minute, Drummer runs a script that gets a list of your Drummer files, and checks against the latest copy in GitHub to see if any have changed. Those that do, get uploaded. GitHub keeps track of the latest version, but it remembers all the previous versions for you. Roady doesn't have any support right now for navigating those archives yet.
      It doesn't have to be GitHub. I'm not sure what kind of infrastructure they've built to operate git at the scale they're doing, but it's probably pretty impressive. By default you'd do it in a document database like mongodb or maybe even a SQL database. You just have to increment a number and insert a new row. If someone wants a previous version, they ask for a different row. The rows can point to each other, or you can use dates.
      But the kind of time machine I want will let me compare versions, restore history, alter timelines, and remap changes between parallel universes in ways that take advantage of the fact that everything is one big mostly-structured outline. That sounds more like git, and less like SQL, so why not use GitHub?
      And once you're using GitHub to persist your infinite outline, what else does that get you? What's the difference between that, and just using a cloud file sync service that provides time machine backups? From the point of view of a Drumkit script, GitHub is better. The GitHub verbs let you use the file system, but not the time machine. You can read and write files, and get directory listings with metadata for the current version. There aren't any time travel-related verbs. However, GitHub also exposes the contents of the entire revision history via consistent urls. So if you keep track of the revision ID, you can fetch whichever version you like.
      Because this is my infinite outline, and not your infinite outline, this would be in a private GitHub repository. Some might put theirs in a public repository, I do not think many would. But maybe parts of the outline should be made public. Roady has the Upload Current Tab… command because I wanted to be able to easily push a private Drummer document to a public GitHub repository. I use this for publishing outlines that I want to share publicly, rather than Drummer's built-in Make outline public… command. Why do it that way?
      Making an outline public in Drummer is certainly easier. It's just a switch you can turn on. From then on, it's publicly available. Anybody can open it up, which is generally the goal of sharing something publicly. If I change that outline, you get the latest version. But GitHub also gives you the previous versions. What if I screw it up? What if you liked the old version, where it was funnier, or had fewer bugs? You can specifically ask GitHub to get you that specific version, no matter what I do to any other version.
      And you don't have to ask GitHub for a version specifically by revision ID, either. These things can have names. Which means more than just "main" indicating the most recent version. The names can be structured, too. So you can construct a name that means "the latest version of the second edition, where they fixed all the typos in the second edition, but not the third edition where they changed all the rules", and ask GitHub for that, without knowing the specific revision ID.
      These revisions are all signed, by the way. You can verify that the bytes you have came from the version you requested. In that way, a GitHub URL is like an NFT. It is a specific token that represents a specific set of bytes, and you can prove where those bytes came from. It's better than most NFTs, because with this particular token, you also get the bytes.
      While we're in the process of constructing this sham, this thing that looks like one infinite outline, but really consists of files scattered over my hard drive, and Drummer, and Twitter, and RSS feeds, we can include others' publicly available outlines as part of mine.
      And if those outlines are published on GitHub, my ability to construct parallel universes and do time travel, gets just that much bigger.
  May 30
    It is exactly what it is
      (2 min read)
      I want to be clear that the formatting shown in the Blackjack screenshots are not side effects of presenting some underlying data structure. They are the data structure. The bold and italics is the syntax. If you highlight something in your Blackjack template, and italicize it, Blackjack will attempt to look it up when that template gets used. There will be some sort of underlying data structure that gets maintained during a round of Blackjack, and I think that's where the bullet probably comes from. ("This is the definition we are using for this round", perhaps.)
      Everything else is just bold and italics formatting you apply with ⌘-B and ⌘-I.
      You have to set off the substitution strings in your templates somehow. Everybody uses curly braces, or percent signs, or triple-@ or hashtags or something that just looks absolutely terrible. It has to look terrible, because it's been carefully selected to be something nobody would ever want to see. Because otherwise, you might mistake some string in your actual content for a substituted value, and all hell will break loose.
      Because Blackjack uses OPML, it is highly structured. There is a definite hierarchy, and you can absolutely traverse the nodes. And there is a way to encode the text content for each node. Drummer will display a small subset of HTML directly inline—b, strong, i, em, a, img, strike, del. This is how you can highlight text and make it bold and italics. Any other HTML tags get displayed with angle brackets. Because Blackjack has a completely different way of representing the HTML you want to generate in your output than simple escape-encoding (that step is already being used by Drummer when it serializes your OPML to and from the server), we sidestep a lot of these encoding issues.
      And, importantly, the encoding is basically invisible. The syntax is literally "surround your text with bold and italics tags, and arrange it into nodes". In fact, it's better than invisible, because it emphasizes visually, and provides collapsible detail, to exactly the things you want to stand out when you are looking at a template.
      Node type assignment, for now, is a sidebar icon I have that cycles the selected node through this list of types: html, code, outline, link and include. Eventually there may be actual attributes defined for the node types.
      But right now, with Blackjack, what you see is literally what you get.
    What Blackjack looks like
      (3 min read)
      Blackjack is a content build automation tool. The templates are outline-based, and use typography and structure to represent the destination output. I'm still working through exactly how I want this to look (and how to make it actually work!). But here's a snapshot of where it's at right now, with a couple examples taken from the Bootstrap demos.
      Here's an example implementation of an image in Blackjack.
      The top-level node, labeled Image, and marked with a bullet, contains the template. The template is just an ordinary OPML outline—there aren't any special attributes that you need an inspector to see.
      However, Drummer provides icons for certain OPML node types, so I've adopted a couple for my own use in Blackjack. The nodes with a computer icon are type "code", and the angle-bracket nodes are type "html". (I keep a full list of the icons I've found Drummer supports in this outline.)
      The template is just a bunch of nodes. The HTML nodes render themselves as containers if they have children, or just as individual tags at the leaves. In the above image, the node marked title will generate opening and closing title tags. The contents of the title tag, the in-between portion, will be provided by the node marked imageLabel.
      Everything in the template that's marked with italics are references to something which will be replaced when the template is rendered. Those substitutions together form what you might call the component's API, which is its set of available inputs.
      Bolded items are component references. The bullet on Image indicates this is where the component is actually defined—other bolded references point back here. Here, we're using three other components. Has and Doesn't have are basic conditionals. If its argument evaluates to true, Has will include its child nodes.
      Content generation systems generally involve some form of cascading lookup to resolve references, and Settings handles this role in Blackjack. Its job is to provide the translations, the mappings, between the inner world of the component, and the outer world of the rest of the page context.
      Here's an example implementation of a card in Blackjack.
      The top-level node, labeled Card, and marked with a bullet, contains the template. In addition to the Image component defined in the screenshot above, this component also uses a List, which is a standard repetition over a list of items. In this case, each card is presumed to provide a list of actions like "subscribe" or "explore".
      This example demonstrates a couple different uses for Settings. At the top, it's used as before to define the available inputs for the Card component. But we can also use it to specify the inputs for a component we're using. Here we're using it in a pretty contrived fashion to provide a mapping for the card's imageLabel property����we run it through some Drumkit before Image gets to it.
    What is Blackjack?
      (4 min read)
      It takes me a long time to write these posts. Not just the typing part, but even getting to the typing part. I've been thinking about the design for Blackjack for at least six months. I am still in the sketching and mockup phase, I haven't written any code that would make the mockup work. Generally at this stage of something like this, I try to have all the pieces clear in my head of what I think I am going to build. Later, when I am actually building and using the thing, I'll discover that probably half my assumptions were wrong, and it's better to do it some other way in practice.
      The other way to approach a design is to build the simplest possible case that works, and then modify that until it does everything you want. The plan-it-all-ahead and upgrade-it-as-you-go approaches can be mixed together, which is what I like to do. If I understand a system well enough, I can skip some of the actual coding parts involved in the upgrade-it-as-you-go approach. Many of those are just to see what works and what doesn't, what's supported by the API or the compiler or the platform. So I also try to start with extremely simple things, and get those working, and build on that.
      For example, my approach to Drumkit has been one of continually stripping away options and conventions inherited from JavaScript. I've noped out of semicolons and iterated through naming conventions and code formatting repeatedly. This is something I do with all my code. I am relentlessly focused on how it reads, how easy it is to understand what it is doing. And how consistent it is. That is extremely important to me.
      If I find a good way to do something, I want to do it that way everywhere in my codebase. Once I've settled on how to iterate over the items in a collection, or fetch, parse, and traverse OPML, I want to use that specific, exact same precise syntax everywhere. Because later, I might find a better way to do it. And if I am consistent, I can find all the usages, and fix them all at once. In fact, if I'm extremely consistent, I can use a mechanical transformation on the codebase to convert it to the new approach. This can be as simple as a set of saved regex search-replace settings in BBEdit. Depending on the size of the codebase, the number of changes, whether I'm doing this repeatedly in different branches, I've also used shell scripts, make targets, sed, gradle tasks and IDE refactoring support. You can't do this confidently without automated testing, though. Automated testing lets you do literally anything to your codebase—including things like transforming it into a completely different programming language—and know for a fact you have not broken anything. When you find something that is broken, you add a new test.
      Drummer doesn't really do automated testing, and there's no good global search-and-replace or refactoring support, which means for me, at this stage, it's faster for me to iterate over design concepts in my head, while looking at a mockup on the screen. Because what I want to be working with, when it's all built, is a Drummer document. So I can just make a Drummer document that looks like it will do what I want, and think about the underlying gears and wires that will make it actually go. Drummer is actually perfect for this, because it is scriptable, so I've added custom icons to my sidebar that lets me twiddle the appearance of my mockup in various ways.
      So I spend a lot of time thinking about that mockup, running through rounds of Blackjack. But what is it, actually? What's it supposed to do? I've been able to see it clearly in my head for awhile now, but haven't clarified that into words.
      Blackjack is for content build automation. It is based on outlines. It is serialized in OPML. It is scriptable via Drumkit.
      Blackjack takes the nodes of an outline as input, applies a transformation, and produces an output. For example, It can transform OPML into other formats, like json, RSS, HTML, Markdown or SVG. Because Blackjack runs in Drummer, it can also fetch source material to transform, and write it back to the internet elsewhere.
      A Blackjack template consists of the definition of the output—what tags should be present, and what their values should be—and how to map input data to the substitutions in the output. It is based on outline structure, typographical cues like bold and italic, and Drumkit.
  May 29
    The infinite outline
      (4 min read)
      I've had some time to think about the specific features that have driven me to using a computer for this project. Mostly they are about the limitations imposed on an application that runs in a web browser on a mobile device. Once you unlock the ability to use a computer, you can then do things like write a native application that runs on the mobile device, with escalated privileges to do those things you're not allowed to do in a browser.
      You can also use all the normal tools at your disposal, which suddenly explode into literally the entire universe of possibilities, because you can do basically anything on a computer. But you get lots of ways to do those things, git, svn, Xcode, eclipse, Visual Studio, macOS, Linux, you name it. It's easy to get overwhelmed by options, which is one reason I have enjoyed working within the limitations imposed by using an application implemented running in Safari on an iPad. There are all sorts of options carved away in a situation like that. Eventually, you may run into the boundaries of what's possible, as I did.
      Drummer provides a cloud file system which basically parallels any other file system in terms of what you'd expect: read and write access to named files. You can get a list of the files in your directory, which includes metadata like size and date. These are private to your account unless you mark a file as public, which means it's available via http to the world. This is where you store your Drummer outlines. I think it's probably possible to store, and serve publicly, other types of files besides OPML. But I haven't experimented with that.
      Drummer provides another kind of cloud file system, which is GitHub. You get basically the same capabilities, read/write access to named files, and you can get lists of files in directories, etc. But because GitHub is based on git, what you get is infinite versioned file history���you can always fetch a previous version. I used these features in making Roady, a mod for Drummer. It continually scans your Drummer file system, automatically uploading changed files to a repository on GitHub.
      What Drummer cannot do is provide read-write access to the file system on your hard drive. Electric Drummer can do this. But neither can access the pictures in the photos app on your phone, or the PDFs in your books app. Drummer absolutely rules at fetching text-based files over http, like OPML or RSS or json, as well as working with tweets. But it can't access anything on your local Wi-Fi.
      What I want is a single outline, synchronized everywhere. This outline is versioned, there is always a time machine at work. Parts of this outline have been configured to watch my local file system. The presence of a new file should be instantly reflected in a change committed to my outline. For instance, adding a new picture or PDF to a folder.
      Because this is my pony, I can also define triggers that run Drumkit code. That means, when my outline changes in particular ways, something will happen. Generally, that means modifying other parts of the outline in specific ways. For instance, adding that new picture to a list of paintings by a particular artist. Then you could run some more Drumkit code—this is where Blackjack comes in—which turns that list into json or RSS. Or, you could poke that information into some other service, like Twitter.
      So, one of the things a trigger should be able to do is reflect these changes in my outline back into the local file system. I want to be able to specify that a node in my outline maps to a file in the file system, and that changes to that node in the outline should be automatically written back out to a specific file in a specific location somewhere. You can think of it as a permanent live instant export to OPML.
      Where Blackjack comes into play is that I'd also like to be able to specify a mapping of the contents of that node into another format. So I can edit some text in my outline, and have it automatically update Someproject.opml on my hard drive, and also generate a new version of Someproject.html or whatever.
      Realistically, this will be one file among many, and so there could be a bunch of content updated, generated, uploaded, saved, pushed, added, from a single change to a single paragraph. That part is Blackjack. And many of these documents will be generated from many disparate sections of the outline. That is where the Loaf Question comes in.
  May 28
    nodeattributes.opml
      This outline contains examples and descriptions of the node types and attributes described in the OPML 2.0 spec, as well as those supported by Drummer and Old School. I keep it open in a Drummer tab as a reference. I've been meaning to clean this up and make it available for awhile now, so here it is.
  May 27
    The checkbox
      (2 min read)
      Six years, or six weeks, or six days, or six months, ago—you know how it is—everything went to hell, and I broke my website.
      Most of the content on the site is actually old enough to drink now. It's for a product that stopped getting major updates in 2003, which was the last time everything went to hell, and I broke my website. Back then, I fixed it, but this time I just let it sit, broken, for years.
      It's been one of those spammy parked search link things, which generally means I screwed up the DNS settings somewhere. Which are at a different company from my hosting, and which I'd configured manually. This is a recipe for many, many hours of research, frustration, and back-and-forth with multiple customer service departments. Just thinking about remembering how it felt to think about this problem causes an unpleasant physical reaction.
      Normal people use Instagram and Facebook, but I've had a website since 1994 or so, and I want my stuff to stay where it should. I put a bunch of stuff on Twitter over the years, but if Twitter ever shuts down, unless I've pulled my own copy and hosted it elsewhere, that stuff's gone. Using Drummer for blogging has actually been part of a giant, stupid, workaround for not having my own website working properly. It has given me a way to create, and, critically, a place to host, without having to deal with fixing everything else first.
      Anyway, now that I'm starting to use a personal computer for personal things again, I took another look at the problem. And fixed it.
      Turns out it was one checkbox.
  May 9
    A range of options
      (3 min read)
      They love you.
      They love you not.
      They love you, but they're afraid it'll get complicated, and for now at least things are simple.
      They love another.
      They get lost, physically lost, navigating their house, and they want you for your compass.
      They're afraid their enormous dog will devour you whole.
      They hunger for you from afar.
      They've been living with the love of their life for the past three years, and have been meaning to bring it up one of these days. They can't help it if this person is literally invisible except when startled.
      They cannot love anyone, ever, at all.
      They love everyone. All the time. Loudly.
      They are desperately in love with you, but can never say. This is not like a curse or spell or anything, they're just kind of an asshole.
      They realized the first time they met you that you'd actually make good eating, and have been fattening you up.
      They love barbecue sauce. And you, but not in that way.
      They're afraid if they said anything, you'd make them hang up the mask and retire for good this time. Not even for one last job, no matter what it would mean for the orphans.
      They love you, but it would really cut into their TV time.
      They just need to fix these several thousand things in their life before they can even think about this sort of thing, you know? They can't get out of the chrysalis just yet.
      They do love you, and always have. You just haven't figured out the passphrase. Which you totally will.
      They are in extended negotiations with the little people from the forest for a very specific kind of ravishing.
      They love you so much, they get drunk every night, swearing to call you up and tell you for real, tomorrow, when they're not so ashamed.
      They can never tell anyone the truth about something which they know nobody would care about, for reasons so painful your heart would simply break if you knew.
      They're afraid their enormous dog will devour the juicy parts before they can get there.
      They have been successfully catfished by someone several thousand miles away, and most of the family fortune has already been converted into NFTs of mp3 fragments downloaded from Napster.
      They have a secret admirer, living in their attic.
      Their heart belongs to music, and music is a jealous bitch.
      They actually have kind of an elephant problem.
      They will not step willingly back into that river. Spoiled, it can never be eaten—the hurt, the corrosion, never carved away. That one definite thing which made it all sparkle and hope has been ruined, ruined, ruined, ruined. You cannot fix this. It is immutable. They will never tell you this, because then you'd take them off your Netflix.
      They're really, really sorry about what's in that crawl space under the house.
April 2022
  April 23
    Something in the way, pt III
      (3 min read)
      You have been given a great gift, like everyone else.
      In fact, you are probably just like everyone else, and it's all your fault, somehow, that you are different, in every bad way it is possible to be different.
      Everything is harder for you than it is for everyone else. Stupid, stupid, stupid, why are you so fucking stupid. Everything you have is broken. Everything you have has been ruined, usually within moments of opening the box, though sometimes it can take years to really ruin something, like a friendship, or a family. There is no moment in your past which is unaccompanied by regret. Even those moments just past. Especially those, far too often.
      You're here to change the world. You have to change the world. You have always been here to change the world. This is why you are here. This is how it is, all the time. It is relentless, like air.
      If there is a problem, you have to solve it. Things can be solved. Things can be fixed. Things can be better.
      We fucked up, everyone fucked up, we're all fucking up, all the time, throughout history, throughout our lives, every minute of every day. But we can fix it.
      Every single thing around you needs fixing.
      There are books on the floor.
      People are dying for no good reason. People are dying for really stupid fucking reasons.
      The dishwasher is sadly clean.
      The people are crying for a king, which people will do, but we got rid of the fucking kings for a reason.
      There are rats in the car.
      Every problem can be solved. You have to solve them all.
      You are surrounded by problems, fractally, recursively, ever-branching, ever-intertwingling, everywhere, throughout the universe, throughout time, throughout reality, and you are going to solve them all, or die trying.
      Why is there time?
      How can people so different someday coexist literally side-by-side as neighbors without murdering each other in great foul gouts of hate?
      How do ghosts work?
      Where is that carriage bolt?
      If you are not solving these problems, all of them, right now, this minute, you have one more problem to solve.
      Every task has prerequisites, requirements, dependencies, FIXME's and @Deprecated and something to move, something to adjust, something to tweak, something to start, something to build, something to fix, something to do, something to plan, something to think about, something to design, something to improve, something to cut, something to solder, something to tape, something to unpack, something to order, something to store, something to break, something to scratch, something to force, something to crack, something to shatter, something to ruin, in a great, spiraling horde of interlocking tasks towering over you like a great vortex that reaches out past the galaxies to the nature of reality itself, and you have to solve every one of them, every single one, each and every one of them, to get anything done.
  April 22
    Something in the way, pt II
      (3 min read)
      Sometimes you write a blog post because it is the only thing you can do.
      The carriage bolt, the drill, the press, the work table, the steel plate, the wood shelf—once a shelf, then for years a dangerous, pointy, coathanger antenna, now to be a supporting brace in lieu of real furniture—the screwing, the cables, the missing carriage bolt, the other steel plates, the cable labeler, the rack diagrams, the patchbays—everything is a project, everything, everywhere you go, every single thing around has something it needs, a drawer installed, a bin packed, two bins sorted, the distortion analyzer reassembled and moved aside so the drill press can do its work on the steel plates, right there, you have every single thing you need to do every single task, and you've finally got it all sorted, everything labeled, everything binned, you know where the small tools are, and the crimpers and bits—
      All you need is some time.
      Sometimes, time is all you have.
      Your insides hurt, but you're finally where you can ignore that gnawing ball, the one that might be muscle or fat or bone or gristle or intestine or liver or kidney or nerve or belly or gut or everything altogether at once trying to chew its way out. Every muscle, everywhere down to the arches of your feet, is exhausted, sore, limp, finally uncramped, given up for now, unable to keep up with whatever causes the ceaseless spasming and heaving.
      These days pass like dreams.
      They are sliced from your life, hour after hour after hour, while you vomit, and vomit, and vomit, and vomit, and retch, and retch, and heave, and vomit, and you can spend two hours working so hard to keep a thought, so hard to just focus one little bit one one thing that isn't the fountains of drool that tell you what's coming, hour after hour thinking about it, sick like a dog, so sick, so sick, sick like a dog, please let it stop, sick, so sick, sick like a dog, but cats, they puke, cats, they have hairballs, so sweet, kitty, so sick, how it must feel to hork your fur up like that, how does it feel, it feels, it feels, it feels, so sick, and it just goes on and on and on and on and you are unstuck from time and cognition and all there is, is sick.
      When it's really bad, four days will pass like this.
      Then you can think again. Then you can do again.
      Sometimes you write a blog post because it is the only thing you can do.
  April 21
    Something in the way
      (5 min read)
      I've decided to get a computer for this project, after all.
      This decision comes at the end of a great, long, stomach-churning chain of solved problems—
      What about the computer that's already there?
      What about the equipment's connected to that computer? Will there be drivers?
      Where do you put the keyboard?
      Where do you put the screen?
      Now that I write it out like that, it doesn't really sound all that bad.
      But it kind of is, because I actually have a lot of equipment connected to that computer.
      There are ten synthesizers, two microphone preamps, eight effects processors, five audio interfaces, five more digital clock/MIDI/ADAT-type things, four control surfaces, two drum machines, two weird keyboards, eight wind controllers,and some other things like microphones and patchbays and stands and whatnot.
      Plus the Otamatone.
      The goal for this computer was basically, fill up every port and connect every device, and then lock it down.
      Freeze all the software and drivers, and just use it precisely as it is, one single, extremely complex device.
      As long as you don't use it for anything else, and don't upgrade anything, you can keep it running exactly like that, forever. Disconnect it from the Wi-Fi, turn off updates, don't use anything that requires always-on access, and it should just keep working.
      I like things that just keep working. I used to customize my Mac, way back in the day, we used ResEdit and utilities galore. I had custom keystrokes, menu items, you name it. But every time I moved to a new computer, it was just that much more crap to bring along. So mostly I make do with the defaults on things like that.
      I had all that completely under control, I swear. I do not actually have much room for equipment. The control surfaces take up a lot of room—think faders, knobs, switches, spread across an entire desk. Where the put the keyboard and screen become big problems.
      So I didn't actually have any place where I could put a new computer for writing software and writing blog posts and filing decades worth of old projects and codebase and pictures and everything else we use a computer for. I haven't used a computer like that for years and years. I've been doing everything on my phone, actually. I mean, I have a big 27-inch iMac and an extra monitor, and keyboard, and trackpad on my desk, but that's the work computer. Someday we'll go back to work in the office and I'll get that precious space back, but for now, there's no place for another computer.
      Hence the iPad. This has been a good, and sometimes frustrating, experience for me, but the alternative was a new laptop or something. I used a laptop for years, but that's when I would move it from desk to desk, not have it in my lap. It's hard to write code on a small screen in a small space, but I've been doing it on the iPad. Anyway, a new laptop is expensive.
      What broke it finally was that I wanted to connect all my test equipment to something. I have a bunch of that stuff, including the usual oscilloscope, spectrum analyzers, harmonic distortion analyzers, intermodulation distortion analyzers, signal generators, and various meters (VOM, wow flutter, capacitance-inductance, etc.).
      Some of this equipment can be controlled by computer, through an HP-IB interface. You can use vintage HP equipment that has the adaptor built-in, or you can get an interface card, or a USB adaptor, or Ethernet. Each option requires an actual computer, though if you go for vintage HP equipment you can actually use one of their calculators.
      But I eventually decided that whatever I get out of that equipment, I want available to me in OPML, so I can manipulate it in Drummer. Which means a computer with networking. Which puts the vintage equipment out of the running. So I went with the Ethernet adaptor. This just makes the HP-IB interface available via telnet, basically. To communicate, just open a socket, send commands, and read the responses. Simple easy, like writing an SMTP or HTTP client/server.
      Except, on an iPad, you can't just open a socket. You can't write JavaScript (or Drumkit) code that can run in a browser and talk to that device. You can make an app that can talk to that device, but that takes a computer to build the app, get it signed and onto the iPad.
      So, I finally decided to get a new (to me) computer, and use it for all of the above. This was an incredibly hard decision, because the new Apple Silicon is super nice, and some of the projects I've got in mind for a computer could really use lots of RAM and processor. But none of my audio interfaces will ever get non-Intel drivers, so refurb iMac Pro it is.
      The old iMac is working fine as a second monitor—right now I'm using a USB video capture HDMI adaptor, like you'd use for streaming, but I've got a thing in the mail that should enable using it as a Retina display.
      Where to put the keyboard and mouse, and where to put the screens, and what to do with the old computer? The answers are: VESA mounts, swivel arms, and a little sliding shelf. When I'm using the control surfaces, the screens will be at the back of the desk. When I need to write code, or do any typing or gaming or anything that doesn't need a bunch of motorized faders, the screens will swing out and down in front.
      So now I should be able to do normal computer-type things, like actual software development with a compiler and everything. It's been just about 20 years since I've had my own computer for that.
      Who knows what I'll get up to?
  April 4
    A brief history of software update
      We used to get our software printed out in a magazine. You typed it into your computer. You had to be careful when typing, because there wasn't a way to tell if you made a mistake, other than by running it.
      You could also buy books with these programs. And there were computer stores, which had the programs on cassette tape. The cassettes were awesome because you didn't have to type it in.
      For Christmas we got Adventureland for the TRS-80 on cassette. It filled 16K of RAM, and it took 20 minutes to load from the tape. This was totally worth it.
      Later on, you could get software on a floppy disk. These were actually floppy at one point. When you bought software, you got a box, with disks inside, and a three-ring binder that was guaranteed to puncture your fingers if you ever tried to open the rings. You also got a registration card, which you absolutely filled in and returned promptly.
      Then you found all the bugs in your new software, and figured out workarounds. And waited, because eventually, someone would mail you some new floppy disks. Generally this would cost you money, if only for the cost of the disks and postage. Also, this took a lot of time.
      So software didn't change very fast.
      Today, your phone wakes up and it says hey, we updated overnight, and suddenly everything is different.
      All the buttons can be different.
      The app can be a labyrinth game where you balance a marble around a maze. And then you update your system, and suddenly it's got little dudes jumping around a cake.
      And so if you were counting on that button, being where it was and doing what it did?
      Yeah, I'm sorry. It doesn't really matter to anybody as much as it does to you.
March 2022
  March 24
    Drummer reliability update
      I have written a lot about Drummer's reliability here in the past. I've run into some bugs that resulted in a lot of frustration, enough that I took some time away from those projects altogether.
      In the meantime, those bugs have been fixed. And Drummer has been absolutely reliable.
      I still use Roady, because it makes me feel safe. But I haven't needed it once.
    Reliability
      We like things we can count on. We depend on this, actually. While we are the most adaptable animals anyone has heard of, we depend on the idea that reality is predictable. Repeated sensory input correlates with an actual thing we can point to. This is how all learning works (including machine learning). We pick up patterns.
      As long as there are predictable things around, we're cool. The jump scare is even a thing because we don't expect the change right then. If a figure suddenly appears at the foot of our bed in the middle of the night, we freak right the fuck out. (At least if it's the first time. After that, who knows? We get used to things. This is how learning works.)
      Most of the things around us don't change, at least not quickly. If you haven't seen someone for awhile, you can see the changes. But if you see them on a daily basis, you won't notice. This happens with kids, especially, but it happens with everything living. We all grow, and change, and we like it when the years slip by. You look at the picture, and there we all are, so impossibly young. How did that even happen? Well, we were all right there, you were, too.
      But most of the other things around us, for basically ever, have been things that don't change. If you have a rock, that rock is going to be the same rock tomorrow. Your house? A house. The street is a street, and the chair is a chair.
      If something breaks, it's generally because something wore out. Look, that chair was going to break eventually, the way you lean back in it all the time. You could hear the cracking. There's a reason that chair broke. It didn't just break all by itself.
      This is why I like test equipment. It does exactly what it is supposed to do, every time. If it doesn't, it is broken. If it is broken, there is a reason. And the reason is going to be: Something wore out.
      There is no other reason for test equipment to change its behavior. It is going to do what it does, every time. (Its performance may drift. Eventually it may get out of spec. That is broken. But you can fix that.)
      But that voltmeter is going to stay a voltmeter.
      And what's more, that button will always do that.
      And it will always be right there.
      Nobody is going to move that switch. That dial will always be calibrated in dB. The connectors on the front will not get moved to the back.
      Computers are never like this. Computers are always changing. I make my living making computers do things they didn't do before I came along. I make them different, constantly, all day long, on purpose, professionally, for pay. Change is what I make them do. But I cannot stand it when computers change. They are always changing! I just want to get my work done. This is the kind of irony that hunts you down.
    Tools for transformation
      I am basically obsessed with the idea of transforming data directly from sources into other things.
      And not doing something twice.
      And being able to do something more than once.
      This comes from my background in publishing and my background as a software developer.
      I want to be able to take a photo, and some text, and reliably apply a consistent transform which converts those files into something new, like a blog post.
      If we need to edit the text, we edit the original text, and reapply the transform.
      (If you can't edit the original text, the edit is now another transform you apply to the original text.)
      I do not want to ever make edits to a generated file.
      If I apply a different transform, I can turn this same photo and text into something else, like a book.
  March 22
    The outline is your user interface
      (3 min read)
      I have been writing software for long enough now that I can pretty much make any computer do anything I want. Switching to a new environment, or programming language, or platform, or whatever, isn't that big a deal. The concepts are always there, somewhere, you just have to figure out what they're called. Sometimes, if you're doing something like FORTH, you need to shift your thinking a bit. The basic grammar there is completely different from, say, Java, so you need to remap things a bit more than usual.
      But most modern development is based around the same paradigm, so rather than learning an entire new grammar, you just need to focus on vocabulary. Drummer, in particular, has a great vocabulary of built-in verbs. But unless you've got the entire API memorized, you still need the documentation. Fortunately, Drummer has DocServer.
      I work all day using an "integrated development environment", or IDE. Features vary, but generally these are apps that combine structured text editing, information lookup, compilation, execution and debug. Developers love making these things. There are so many, I don't even want to name a single one. We can't help it, we have a drive to do this. We keep making IDE's because they're useful features to have in one place.
      One of the key features is context-sensitive lookup. Once you get used to being able to command-click on something, and have something useful happen—whatever that is—you miss it when it's not there. Different tools provide these services differently, but generally you get used to being able to click on something and do things like:
        Find where that function is used
        Find where that method is overridden
        Find the documentation for this system call
        Move this method to another class
      Being able to highlight a verb, and get its documentation immediately, is something I'd missed when working in Drummer.
      DocServer is made possible through its OPML file, which I've got bookmarked in Drummer because I find that easier than using DocServer itself. Because that file is structured, we can do other things with it, too. And because Drummer is a scriptable network outliner, we can use that file to add features to Drummer itself.
      I added a new icon to Drummer, which looks up the documentation for whatever you have highlighted, and inserts it directly below the current node.
      Highlight the verb you want to look up, and click the icon.
      We fetch the OPML file, process it, extract the data we want, and insert it directly into the outline.
      Because the OPML file we use is barely structured, we can apply some heuristics to make it even more useful. In this case, we emphasize the subheads, and automatically expand the nodes. Some documentation includes extensive example outlines, for example, a returned data structure. We can automatically collapse those sections. When you're done, just delete the node. (Or leave it, the docs are inserted as comments.)
      You can try it out for yourself, just copy-paste the outline into your Drummer icon file. See this page for details.
    A scriptable outliner lets you turn barely structured data into structured data
      The thing about using an outliner to maintain barely structured data, is that it's all visual. You can just see what the data is. There's nothing hidden.
      Here's some settings from my ST 1710A calibration outline:
        INPUT switch
          .1 mV
        ADJUST control
          CAL
      You can represent something like this as structured data, you just need a schema. For example, you might define a CONTROL element, and declare that it has a NAME, a TYPE and a VALUE.
      This might look something like this:
        control:
          type: "switch"
          name: "INPUT"
          value: ".1 mV"
      With structured data, you need either a dedicated application to view it, or inspectors. Or you're looking at the source. For example, you generally just look at raw json to see what's there. With XML, you tend to just look at it, too, because all the interesting stuff is in attributes and tags. Browsers have offered XML viewers throughout the years, but you're still looking at the source, just with the ability to collapse sections.
      Structured data is super useful, of course, and the world operates on structured data. RSS is a structured format, there are elements and attributes defined, and you need to follow them or your feed won't work properly. All the XML-based formats are structured in that way.
      OPML is structured like that, too. It's a completely machine-readable format, but it can represent structure in flexible ways. For example, OPML has attributes and elements, etc. Different OPML documents, constructed for different purposes, can use completely orthogonal sets of attributes.
      In fact, I can use OPML to define a schema just like the one described above to represent these settings as structured data. I can define a new node type, and specify a few attributes, and now I have a dedicated, structured, formal definition for a data format. And once it's structured, it can be manipulated easily in completely different, non-OPML-based contexts.
      Of course, what you really want is a way to get from the barely-structured OPML to the structured format, and back, easily. More on that coming up.
  March 19
    DocServer is barely structured data
      DocServer is a great example of what I mean when I refer to OPML as "barely structured data."
      Here's a link to the DocServer page for the verb speaker.beep().
      DocServer is driven by this OPML file, which contains an outline of all the verbs in Drummer's scripting language.
      (I have a bookmark in Drummer for this file so it opens in a separate tab. That way I can quickly drill down to find the section I want, pin it, copy-paste, etc. I find this more convenient than using DocServer itself, actually. I also made this icon which you can add to Drummer to do inline lookup.)
      Here's an example of what the outline looks like in Drummer.
      speaker verbs
        speaker.beep
          Syntax
            speaker.beep ()
          What it does
            Makes a standard beep sound on the computer's speaker.
          Notes
            It's useful for confirming an operation was done, or otherwise to attract the user's attention.
          Returns
            undefined
          Example
            speaker.beep () === undefined
              true
      There are no special attributes or elements. Just an informal convention: Each verb is described in an outline. The top-level nodes are rendered as bolded subheads. Anything else underneath that is rendered as an indented outline.
      You don't have to have a Syntax section, that's just a convention. In fact, you can use DocServer to serve up recipes in a cookbook.
  March 18
    How does Roady know there's a newer version?
      (2 min read)
      One of the first things I made sure that Roady could do was to check for a newer version. Roady does backup. If you use it, you probably want to know if I've fixed a bug. There are a number of decisions that go into designing a software update mechanism, but today I'm going to focus just on how it actually works, and skip the why part for now.
      Roady's Check for Updates… command really only has to do a couple things. It needs to figure out what the newest available version is, and compare that to the currently running version. Roady uses semantic versioning, so it has structured version numbers—major, minor, patch. Right now, that's 0.3.0. Anything with a version like 1.0.0, or 0.4.1, or 0.3.1 is newer.
      Converting a version string to digits so you can compare them is a stupid-looking regular expression, and the actual "this is newer" is a normal set of if-then statements. What I wanted to point out today is the mechanism by which Roady determines the newest available version.
      Roady is distributed as a single OPML file, which contains an outline that you copy-paste into your scripts menu file in Drummer. In that OPML file is the rd-roady-version header, which contains the version string.
      To get that version string, Roady reads the entire remote OPML file, parses it, converts it to a JavaScript object, and then gets that one little property.
      Here's the code:
        const url = "https://raw.githubusercontent.com/PostMonsterG/Roady/main/Roady.opml"
        const fetched = http.readUrl( url )
        var latestversion = opml.parse( fetched ).opml.head[ "rd-roady-version" ]
      Not much there at all. It tickles me how much work is going on behind the scenes.
      Living in the future is fun.
  March 17
    Why I need a scriptable network outliner
      (8 min read)
      As much as I like to credit myself for being a great writer, able to communicate complex subjects clearly and succinctly, I am of course no such thing.
      I've been pretty coy here on the blog part about what I'm actually up to. That's because I want to get everything absolutely perfect before putting anything out there. Which of course is stupid, and the lesson the blog part is teaching me over and over and over. It's OK to talk about works in progress. Narrating your work is part of what blogs are for.
      In that spirit, here's an overview of a small piece of what I'm building, and why I'm using OPML and Drummer to do it.
      I like test equipment, and I cannot lie
      I have a vintage Sound Technology ST 1710A Distortion Measurement System. You connect it to audio equipment, and it allows you to determine how well that equipment can handle processing the purest possible signal. Mine has Option 003, Automatic Level Set, which is handy, because it eliminates several steps when taking measurements. It also has Option 004, which is the Intermodulation Distortion Analyzer, which adds a bunch of new steps, but you also get a different kind of distortion measurement. This of course is known as a win-win, because more things to fiddle with means more fun.
      Naturally, mine isn't performing to spec. Failure to settle, wobbly generator output, nulling problems, tuning indicator, all the classics. Naturally, the PDF manual I found years back is for the wrong model, and is missing pages, etc. This makes fixing things difficult. If I had the slightest idea what I'm doing, this would probably not be so difficult. But I do not.
      I recently got a print copy of the owners manual, and it matches my machine precisely. It has full calibration instructions, theory of operations, schematics, performance tests, everything. So I've been going through the steps, very slowly, to get the machine into shape.
      There are a lot of steps. They're arranged in numbered outline form, actually, so you can use them like a checklist.
      Here's an example. It's not verbatim from the printed manual, because I'm still deciding how I want to format it.
      Oscillator x1000 frequency range adjustment
        FREQUENCY pushbuttons
          X1000 x 10 = 10 kHz
        Monitor dc voltage between DC and ground, and frequency of oscillator.
        Adjust trimmer capacitors across C33 and C38 with an insulated trimmer tool until
          dc voltage is in the range of 6.5 V to 8 volts
          frequency is 10.0 kHz ± 1.5%
        FREQUENCY pushbuttons
          X1000 x 100 = 100 kHz
        Check that
          dc voltage is in range of 6.5 to 8 volts
          frequency is 100 kHz ±1.5%
        Repeat until voltage and frequency readings are within specifications stated
      Typing all the things
      I've been transcribing all the tests, and all the calibration steps into an OPML outline, manually. This is a weird thing to do. What I should do, is scan the pages into a PDF, and add it to the rest of my library of scanned owners manuals. If I want the text, I should use OCR.
      I am retyping all the steps because sometimes I like typing. This is not the same as using a keyboard to compose text. I am talking about sitting with a stack of pages propped up to the side, and you look at the words, and you type them in. I used to do this for a living, actually. This was a thing you could get paid to do, sit there and type in lots of text.
      Sometimes you were typing paragraph after paragraph of readable, understandable sentences, with ordinary capitalization, quotation, formatting, etc. But often, the kind of text you got paid to type was something much more complicated than plain prose. Lots of tabbing and formatting, and especially capital letters.
      Technical documentation loves caps. The secret, of course, is to use the CAPS LOCK key. That's what it's there for. Eventually, you get to the point where you use it in places where ordinary people wouldn't think to. For example, WHEnterpriseObject. When I typed that just now, I used caps lock for the WH (and again just now). But I switched back to the shift key for the E and O. That is probably insane, but when you are good with capslock, you are good with capslock.
      And you are typing fast, 90 words a minute or more. You can get into a flow, where you can be thinking about something entirely different from the words you are typing. But you can feel a typo, and immediately backspace to correct, and you fix it by retyping the word, even if it was two words back. This can be fun, especially if you're interested in what you're typing.
      Barely structured data
      It is super easy for me to get all caught up in normalizing my data structure. If you just model all the possible relationships properly, you can totally accurately describe the world and every single thing in it. This is seductive.
      Of course, the real world is full of data that is just barely structured. For this project, I could design a schema that modeled all the various control types—switches, buttons, dials���and their various states. I could specify tags and attributes that define connections between pieces of equipment, and test points, and voltages, and readings.
      Then, of course, you want to define the schema so it handles all the other test equipment. And all the other possible instructions, and settings, and values… You see where this goes. In the end, you have this world of perfectly formatted, absolutely reliably constructed, consistently populated files, all with consistent use of units, abbreviations, spelling, and everything else, because you have thought carefully, in advance, and foreseen every possible situation that could arise.
      This is how we get file formats. We are all geniuses and can figure out in advance precisely how we will want to use this data in the future. And because we all agree to use the same format, we can all share files and there is never any problem with which version of what program wrote what file.
      Anyway, in the world I live in, this is not actually the case. Every time you think you know everything about how to model something, you end up with some exception somewhere. Suddenly you've added an entire programming language to your file format, and you end up with PDF. Or something that can send or receive email. (Either your file format turns into a Turing complete language, or your application recreates SMTP. This is the way of the world.)
      I'm using OPML because it's what I've lately been thinking of as "barely structured data." That is, it's structured, but not so that you need to specify everything in a schema. It's close enough. It's a machine-readable format, and if a particular set of documents use consistent conventions, it doesn't matter if they're not the same conventions as other valid OPML files. You can still read it, manipulate it, and write it, with a simple editor. And there's no lock-in, I'm not stuck with Drummer. OPML is dead simple, just complex enough.
      Why would you even need this
      As I said above, really all you need is a PDF of the manual. But maybe these steps are just one small part of a larger outline, that contains all the relevant documentation for that piece of test equipment.
      For instance, I find myself wanting to know what connectors there are on the back, and what their specs are. Same for the ones on the front, actually. It's easy for me to forget which connector puts out 0–10 volts, which one puts out 0–0.1 volts, and which setting is for peak and which is for average.
      Once I have that, I can actually just have the outline for the ST 1710A be just one part of a much larger outline, which contains all the documentation for all of the test equipment in the lab. Find the piece of equipment, zoom until you find what you need, pin it, there it is. An outliner is perfect for this sort of thing.
      I can turn it into something else
      What else could I do with this outline of the things in my lab? If I'm reasonably consistent, a lot. Once you've imposed even a little bit of structure on data, you can start applying heuristics, and break it apart even more.
      I can extract pieces of the outline, and export them into a page layout application, and generate my own fancy printed custom instruction manual for the entire lab ("so you've purchased a bunch of dodgy test equipment on eBay").
      I can make custom quick-reference cards. HP equipment often has these pull-out cards, with summaries of key information.
      I can copy the calibration steps into a new document, and use them as a checklist as I work my way through fixing something, recording the voltages measured, adjustments made, notes, etc. I can also just include this right in the big outline of things, because it's a maintenance record, and why not keep it right there.
      I can export that measurement data into a fancy PDF data sheet with all the performance data in one place, which might be useful if I want to sell something later.
      I can write up my own instructions, for how to make particular measurements, involving multiple pieces of equipment. I can reference the specifications for each of the connections, and generate my own SVG wiring diagrams. (You can represent a wiring diagram in an outline, they're just nodes and connections.)
      Scripting all the things
      A lot of my test equipment itself is scriptable, too. Most have HP-IB connections, which allow for control over a wire. There are a lot of applications for working with these, some free, some expensive. The commands for controlling test equipment are pretty straightforward. Most of the sample code in the manuals for my equipment is in BASIC, actually. I'm not afraid of writing code, I can make a computer do anything I want. I haven't got any solid plans yet for this, but I think there are some pretty sweet opportunities here.
      Being able to script my equipment, my data, my documents, my workspace, and the rest of the internet, too? Yes, please.
  March 15
    Previously on the blog part
      Drummer is fucking awesome
      Some things about JavaScript
      What is with the fucking swearing
      A heavy-handed parable about finding and fixing bugs
      We're going to keep doing this until we get it right
      Things I'm glad Drummer doesn't have
      A partial list of some things I may have actually been wrong about
      I want a parallel universe time machine that lets me break off chunks of reality for others to play with
      Keeping that little bottle safe
      Another bottle episode
      It comes straight from the top
      Stupidy, or why Mark Zuckerberg may actually be the biggest fucking asshole in history
      Typographical escapes
      Flying
      Remembering JavaScript
      Undo
      Hello, Blackjack!
      More about my goals for Roady
      Roady: What do we back up, and what do we call that thing?
    Monthly archives for the blog part
      Here are direct links to the monthly archive pages that Old School automatically creates for the blog part.
      2021—October, November, December
      2022—January, February, March
  March 9
    The text exploder
      I have a problem where every problem has another problem that solves that problem, except of course there's a problem there. And that, of course, means another project. Here's one that I plan on writing, but not just tonight. I don't have a good name for it yet, but I think of it as the text exploder. it implodes too, but the exploding part is more fun to think about, I guess.
      It's a writing tool, for writers. (This is distinct from a text manipulation tool, word processor, code editor, etc. Specialized tools for specialized purposes.)
      The text exploder iterates through nodes in an outline. It assumes the nodes are paragraphs, made of sentences. When it's done, each sentence is a separate node, and there are extra blank nodes between paragraphs. You explode the text out into sentences, drag them around to rearrange them, and then implode the text back together.
      This is not a hierarchy thing, probably. I haven't made this tool yet, but in my head all it does is stretch the outline out, like a string of fresh-cut paper dolls, or an accordion. You shuffle, it zips back together when you're done.
      I want this because I've noticed that a lot of what I write, I could actually shuffle the sentences around, and make it better. Same words, in a different order. And I am lazy, and it is a pain to select a sentence in the middle of a paragraph. And using cut and paste commands to do the rearranging is not the same as seeing the text repositioned visually. And if you cut something, and forget to paste it, you have lost it. If you're just dragging a node, you let go, at least it ends up somewhere.
      I've been poking around at a blog post for awhile now, but it needs rearranging. It needs the text exploder. So every time I think about sitting down to work on that post, I should really be working on the text exploder. And then, I end up with no blog post, and no text exploder, either.
      So this time, I am tricking myself: I will write about the text exploder.
      At least this way, I get a blog post out of the deal.
February 2022
  February 24
    Grooving up slowly
      One of the benefits of having literally dozens of projects to work on, is that when I get discouraged on one, I can work on something else for awhile. The corollary, of course, is that makes it pretty easy to never actually finish anything. This has been my curse my entire life. I have projects I began thinking about in the 1980s and still haven't finished. (And still intend to get around to finishing someday, really.)
      This endless puttering erodes confidence, and you need to be fearless to actually stick a fork in something and declare it done. I find this easier when I'm doing it for someone else, a favor, a promise, a paycheck, a defined end point, a deadline, a customer expectation, a job duty, a contract, something. When it's just me, it's easy to set something aside and work on something else. Finishing it means making decisions. (Or doing the boring part.)
      That's one reason I pushed myself hard to get Roady out the door—I have more planned for Roady, a lot, but it's useful now. It's something. It's a thing. It exists. And I made it. It's been a long, long time since I had so much satisfaction finishing something, that I had literally forgotten how good it feels to make something, go through it bit by bit, and make everything as right as I could, and then publish.
      (Even two months later, I still sing the "I did it! I did it!" song to myself and do a little dance, because shipping is fun.)
      So I've spent the past month working on everything but the blog part, Blackjack, and the rest. Basically, working on some of the things that Blackjack is there to help me get out the door. Because what I am building here is, well, my ideal dream-making machine. I am trying to set up an environment where I can create, make and publish basically anything: blog, novel, script, song, animation, cartoon, kids' science show, electronic goban, chess-playing robot, stereo equipment from a parallel universe, etc.
      And while working on one of those projects, I found myself needing to organize some information. I spent a couple minutes thinking about it, and realized that what I really needed was an outliner. I fired up Drummer for the first time in weeks, and it turns out, I was right, an outliner is way better than a sheet of paper for that kind of work. And those few minutes reminded me of some tools I want to build, and how much fun it is to work in this environment.
      So here I am, back at the iPad. I'm not back in full Blackjack mode just yet, but I'm getting there.
      This is going to be fun.
January 2022
  January 13
    Blackjack.opml got eaten
      Thanks to Roady, say hello to Blackjack2.opml
      Seriously, seriously getting tired of this shit.
      I was really looking forward to working on this tonight, and now, even though I have my file back, I'm just discouraged.
      Maybe next week. I know software is a process and there will be bugs, and fixes.
      It'll be OK.
  January 11
    A couple quick rounds of Blackjack
      blog.opml → Blackjack.opml → file1.html, file2.html → GitHub Pages
      artDownloader/art.json + Bootstrap templates ��� Blackjack.opml → GitHub Pages
      Instant websites, instant design, instant hosting.
      All you need is a Twitter account, a GitHub account, and a Drummer account. And if you've got the Twitter account, you're already set for Drummer.
      If you put the template OPML files at predictable, named locations, they are then referenceable and forkable in GitHub. For example, I publish my "make a slideshow" template. You can then reference it easily from your own templates, at a predictable, consistent githubusercontent url. You can also make your own, and publish it, and if we all agree on how to structure and name these things, you can fork mine, and I can fork yours.
      Because your website data is structured, you can run it through different templates. And if it isn't structured, because Blackjack is all about extraction and mapping, you can have a round of Blackjack that looks like this:
      somedata.html �� Blackjack.opml → structureddata.json → Some other processor → Blackjack.opml → structureddata.opml → Blackjack.opml → some other hosting service besides GitHub
      I've been building and working with websites, templating languages, structured data, community and content management for a long time. (My first professional website templating language dates to 1996 or so.)
      Nothing works the way I want it to, so I am building my own. With Blackjack.
  January 10
    Doing my own thing, with Blackjack
      I shouldn't be working on Blackjack right now, I should be working on Roady. I know what I want next, I have the tools to build it, I can be confident Drummer won't eat my outlines. Well, at least, I can be confident that if it does, I can get them back. I am seriously, seriously more tired of writing about how Drummer ate blah blah, than you are tired of reading about it, you wouldn't believe.
      So why is Blackjack so incredibly important right now? Because, well, Old School is eating my blog.
      Actually, as far as I can tell, Old School is eating all the blogs.
      As you scroll down the page page at http://oldschool.scripting.com/PostMonsterG/ you will see some recent posts, sorted by creation date, newest first. When you reach the bottom of the page, there are no more posts. This is the entire extent of discoverability for posts on an Old School blog.
      If you have a link to a post on an Old School blog, you have a link to that post only. You cannot get to the post that preceded it, by creation date, nor the one which came after.
      That is it, that is the entirety of discoverability for posts on Old School. When you reach the bottom of the page, you are done, there are no more posts.
      I've been OK with this, because I've been building my own version of Old School, something to turn blog.opml into Fancy Blog.html. And I am slow, and only work on this stuff in the evenings, so I can be patient. It's OK for me if the entire history of the blog is on one page. But now, posts are disappearing from the bottom of the page.
      I started my blog on October 17. As of this writing, the earliest post visible on my blog is from November 24. Everything else I've written before that, from a reader's perspective, has completely vanished.
      Anyway, the articles are still there, at their existing URLs. Last time I went poking around with seeing what URLs on my blog did, I think there's some sort of archive page, by month, or year, or something. But there is no way that I can find, to tell Old School that it should, perhaps, include links to those archives, possibly off to the right-hand side, where every other blog has theirs.
      You'll note, Dave's blog does not have such a sidebar. Old School doesn't do that, because Dave doesn't need it to.
      I was seriously surprised to discover that my blog page suddenly was missing posts. Like I said, I don't care, for now. I can go back and start adding inter-post navigation by hand.
      But the situation has definitely increased my personal need for a functioning website templating system.
      So I am building my own. With Blackjack.
    Absolute clarification
      I want to make it one hundred percent clear that my previous post is not some whining about how Dave won't use my Concorddd. My Concorddd is a broken piece of shit.
      I am whining about the fact that there has been a known data-corruption bug with a known fix, unapplied. Maybe this has been actually fixed in the version of Concord that Drummer uses, and I should once again shut the fuck up about shit I don't know about. But I know I exercised that bug yesterday, in Drummer, to see if it was still there.
    Fun with irony
      I have a brain thing with irony, where I have to avoid it. I do not know why, this is just how it is. I do not want to die in a stupid, ironic way. I do not want to be embarassed socially, ironically, because I can't spell embarrassed. But irony always finds away. Irony hunts me down.
      For example, the issue I was investigating in yesterday's post, when I crapped an unwanted spam link to the repository for the code I wrote to provide backup for Drummer files into a thread in a Drummer support forum where others were posting their own experiences with backing up Drummer files, was actually about Concord.
      The issue came up for me from the Drummer side, because Drummer uses Concord. And inside Concord there is a bug that will eat data. It is easily repeatable, you can do it yourself, and if you've tried to put two img tags into a Drummer node, you have run into this yourself. I ran into this, a long time ago, and concluded that image tags weren't supported in Drummer, and that the ability to display certain kinds of HTML inline at all was a bug. I didn't find complete documentation about what tags are permitted, so I stick to the ones that I know work: bold and italic.
      My Concorddd project is on pause, mostly while I wait for Dave to release Glorp or whatever it's called, because I think that's how he maintains Concord, and it's probably a better experience than what I'm going through with GitHub's Visual Studio web editor. The whole reason the roadkit format is even a thing is that I wanted a way to manage posting my Drumkit samples to my drumkit-samples repository, a way to hold a repository in a single file. Later, after Drummer insisted on continuing to just keep on eating my fucking files time after time, and I had had just about the fuck enough with this fucking situation, and wrote Roady over a weekend and a couple of evenings, it has become something else. I don't want to hold a repository in a single file, I will use Dave's format for that. The roadkit is different, it is just for me to be able to quickly template up new mods for Drummer.
      I have decided that Roady is a "mod". It is not an app. I came upon this terminology talking with my son. Who, and now we are getting close to returning to the whole irony portion of this post, asked me this weekend, when I should have been figuring out how not to lose to him again at Stratego, whether or not I worked for Drummer. I explained, no, I do not, Roady is just a mod.
      Part of the reason I have the blog part is because I am building something. I am building it here because I have not been asked to build it for my job. My job is to build what I am told, and fix what I am told. Even if fixing that thing is only an issue because the several times I fixed it previously ignored. This can be disheartening.
      So I ran into this particular data eating bug in Drummer once more, and thought to myself, self, you actually know what this is, either there is a seriously stupid recursive descent parser in play, or someone is attempting to parse HTML with regular expressions, and one of them is too greedy. And self, we know where this is in Concord, actually. I should go take a look, I bet it is that one method.
      I have learned a lot of lessons from the Concord source, and one of them is that holy fucking shit cycles do not fucking matter.
      Here is one thing that an app often does: It inhales a file format, probably does something with that file format internally, because file formats are generally not suitable for use as an internal format, and then it can exhale that same file format. In Concord, this is a pair of methods, called xmlToOutline and outlineToXml. When I first ran across them in my initial surveys of Concord, I figured they were for import and export.
      Here is a snippet from the Concord source: this.xmlToOutline(this.outlineToXml());
      What this snippet does is, serializes the entire outline to XML, and then reads it back in, as if it were loading it from the filesystem.
      This is insane. This is genius. I would never, ever have thought to do something like that in my life. It is such a sheer, wanton, waste of cycles, compared to how I came up, that I am slowly beginning to understand why people just shrug at abominations like bitcoin. I have since leveraged this concept in Roady. Roady does things in ways that I never, ever would have considered ten years ago. That's not due to technology marching on, this is just me coming to grips with how the world actually works these days.
      You cannot look at Concord sideways without it calling that snippet, by the way. Concord is serializing and deserializing your outline, all day long. Well, maybe not quite all day, but often. And here's the thing about that snippet: It has to be one hundred percent, absofuckinglutely reliable.
      Guess where that img-tag eating bug lies? In the code that serializes and deserializes the outline into and out of XML. So to me, this is a serious serious bug. You can load a perfectly valid OPML file, and have it be corrupted, just by looking at it. I don't remember, maybe you have to expand a node or something to trigger, I don't feel like looking right now. But the point is, Concord can eat your file. And you can see this by making a simple pair of img tags in Drummer, and watch them vanish.
      So this is the bug, which I finally tracked down, and found the code, and found the regular expression (do not get me started on using regexes to "sanitize" HTML), and fixed it. And then went off to GitHub to file an issue. This is the bug I was dealing with when I ran into that thread about backup. I posted a quick mention of Roady, moved on.
      Where I moved on to, was the Concord repository. Where there is an issue which looked like it talked about the same thing. So rather than filing a new one, I post my solution as a comment. Because this is a terrible way to propose solutions, I also included a little test case to exercise the fix, so it could be reasoned about separately from the rest of the Concord source.
      And now we get to the funtime irony part. Upon re-review, I realized that someone else had beaten me to it. With the exact same solution, in fact.
      In fucking 2020.
      So much fun to fix things, only to discover that they have already been fixed, and the fix ignored. I guess that's probably two reasons Concorddd may lie fallow for awhile before I get back to it. I get enough of this shit at work, where at least I can get paid to be ignored.
  January 9
    The giftie gie us
      I saw a note in the Drummer change notes the other day about posting links in the Drummer support forum, and thought to myself, "Geez, I wonder what kind of knucklehead would try to promote a product in there?" I thought, well, some people aren't going to like that, but it's not what a forum like that is for. And if it's your place, your rules.
      I ran into this recently with an issue I posted there, where I had completely misconstrued the nature of the forum. I had run into an issue with Drummer. I figured out how to fix the problem myself, but realized maybe others might want to know. So I posted a thread describing it.
      Dave asked a question that immediately clarified in my mind just how I had missed the point about how the place operates. It's for "I have a question for Dave and I need support," not "here's something I learned about Drummer." Which is 100 percent fine. Some support forums are like the former, some like the latter. But I mistook one for the other.
      This for me is a particular kind of social error that I find incredibly, incredibly, soul-crushingly, horrifying. You can't fix it, you can't undo, you can't change people's first impressions. These are personal issues, it turns out, my internal mental state has no impact on the outside world. Only my words, and actions.
      I am getting better about understanding this about myself, so I have learned to give myself some slack. I explained, and intend to do better in the future, which is really all anybody can ever do in a situation like this.
      I would never have posted this to the blog part, but I am slow, and just now put two and two together: Dave had to re-emphasize the whole "no links" thing because of something else I'd posted, in a completely different thread.
      I'd been looking through the forum for issues, to check for duplicates before creating a new issue. This is important, if the developer already knows about something, there's no point in raising an issue again. That is just wasting everybody's time.
      Anyway, I ran across a thread that contained various suggestions from people describing things they'd done regarding backing up their Drummer files. Naturally, since I'd just been working on Roady, I wanted to share, so I posted a link. And then Dave had to clean that up.
      I've got some experience with building communities, both from the software and moderation side. Someday I will write more about that. I can tell you, the last thing I would wish on anyone is additional work like that at my expense.
      The fact that it took my brain literally days to put it together that I had been the one, well, that is the kind of irony that hunts you down.
    Concorddd
      (10 min read)
      Making Roady is actually a distraction from Concorddd, which was a distraction from Blackjack, which isn't actually a distraction from anything, because I really am building something. It is layers within layers of stupid projects around here, people.
      I've said that it is an unreasonable thing to ask Dave Winer to add multiple undo to Drummer. Because we expect to be able to open a new document, work on it for several hours, then hold down command-Z and watch it unstitch itself back to an empty document. And then hold down shift-command-Z, and watch itself stitch itself back together, as if a ghost was doing it. This is my fundamental baseline expectation, and if you think about it, it's the model you probably have in your head, too.
      My brain gets caught in loops, and sometimes I can't get out until I figure out how to exit the loop.
      In December, I had a bunch of Drumkit things I was working on, but every time I sat down with the iPad to start coding, I ended up looking at the source for Concord on GitHub. I can't help it. I want multiple undo, and this is code, and I can read it, which means I can understand it, which means I can do this.
      It is an unreasonable thing to work on—I have no use for an outliner, outside Drummer. And I can't tell Drummer to use my outliner instead of Concord. But I've learned that I should work on the things I can't stop thinking about, so instead of working on my Drumkit projects, I worked on something else.
      ~
      Concord is an outliner written in JavaScript. It's not a zillion lines of code, but it's complex. I have spent a lot of time just reading through it, understanding what I'm looking at. The code is nicely separated. There are groups of functions for dealing with an editor, functions for outline manipulation, keystroke handling, and the rest of the glue you'd expect for maintaining the user interface for an application.
      To be sure of something like this, you want to check everything. Just because you found a function called undo() doesn't mean that's it.
      Maybe that's not really the place where undo happens. Maybe it's in the editor code. Maybe it's in the underlying data manipulation code. Maybe it's in the control layer glue. There are usually a whole bunch of steps involved in a single user interface action. Where do you draw the line between what is undoable, and what is just a temporary state that gets us to the next undoable state?
      There are a lot of Drummer's verbs for manipulating outlines paralleled in Concord's functions, too. This is because Concord is not just an outliner, it's a tool for building outliners. I suspect that some or even most of Drummer's outline manipulation verbs call these functions in one way or another. This has implications for anybody who wants to muck about with the undo/redo mechanism, because suddenly you have to think about code-based manipulation, not just undoing user interface actions.
      There's a lot of stuff Concord does that looks, at first glance, like it might be related to the undo–redo mechanism. In particular, there are markChanged(), clearChanged() and changed() functions. But they are, as far as I can tell, one layer below where we want to add multiple undo.
      It looks like the undo–redo mechanism was built on top of those methods, and my read is that the magic is in the saveState() function. That is the place, more or less, where state gets persisted in Concord for undo. There's another spot, for handling dragging changes, but its code parallels what's in the saveState(), and, importantly, undo() functions.
      I love reading other peoples' code, I have ever since I typed in BASIC programs from Creative Computing into my TRS-80 Model I. You always learn something new. And I love having my expectations challenged. I am slowly getting used to just how fast computers are these days, and how much storage is available, and how fast and reliable networking is. In my head it is still 1977, so it can be hard for me to really get what you can do with that sort of thing.
      In this case, what I discovered was Concord's undo mechanism. Remember what I said earlier about how, if you really wanted, you could get undo by simply copying the entire document?
      Yup. If you trace through all the parts, you'll find a couple pieces of data that Concord uses for its undo mechanism. It keeps track of the editing state (are we in text mode or outline mode), the selection range (if we're in text mode), and the document. Undo and redo involves swapping the document, and those other two things.
      ~
      My theory is, I can put those chunks of undo-related data into a single object. And then keep a list of those objects. Every time we save state, we add to the list. I've already determined we only save state when it's important enough to warrant an undo.
      To undo, you step backwards one place from the end of the list, and restore that state. If you undo again, you step backwards again, and restore that state. You can keep doing that until you unwind the entire list.
      To redo, you step forward on the list, and restore that state. You can keep doing that until you go through the entire list of states.
      If you save state while you're in the middle of the list, you cut the list in two pieces. The part you keep ends with the last state you can use. This is what you'd get if you undo the state you're about to add. We can discard the rest because that part of the list is useless in this universe.
      (In a parallel universe, those discarded states may still be useful. Providing a good virtuality for navigating and selecting from those parallel universes is left as an exercise for the reader. Remember, these are entire documents, so maybe we should have a branching outline of undo states, rather than a simple list...)
      ~
      When you're building tools for developers, like, say, an outliner that is also a tool for building outliners, you really, really, really don't want to fuck shit up. People are always fucking shit up, and it drives me bananas. And it is easy to fuck shit up, when you have no idea what that other shit even is. Which is the situation you are in, when you are building tools for developers, like, say, an outliner that is also a tool for building outliners.
      Which is to say, I want to be extremely clear that I have no real plans for this thing. This is mostly me getting annoyed at something, wondering what's involved in a fix, needing a useful "hello, world"-type project to put the GitHub web editor through its paces, and poking at it until I got it to do something. In particular, I have no real insight into how developers actually use Concord in practice to build things.
      There is a very good reason that Dave has a note in the readme for Concord to the effect that the code is never the hardest part. It really isn't. I can't say, "here is how to add multiple undo to Drummer". I'd like Drummer to have multiple undos. I have no idea if this is the way to do it.
      To ensure there's no confusion between my horrible mangling of Concord, and the real thing, I'm calling my fork Concorddd. (The multiple D's are for multiple undo.)
      ~
      If you look through the history of the commits on the Concorddd fork, you'll see a hilariously huge number, as if I was using the project's public GitHub repository as my workspace; as if I had no local environment in which to test my changes; as if I had no way to preview the results of any changes to the code. That is actually the case. You can think of it as, I take this stack of carefully prepared punchcards across campus, and run them through the reader, and wait for the printout. One of my regrets is that I waited a semester to take assembly language programming, because I wanted to use the Apple II lab instead of the punchcards. I should have used the punchcards.
      GitHub has a web version of Visual Studio, which you can call up by hitting the period key, in any web browser, including Safari on an iPad. It's a real development environment, kind of. You can't run or debug code, but you can actually commit changes. They're stored in local browser storage, which I don't think is particularly stable on a mobile device, so you'd be nuts to use it for any sort of serious development. Plus, there's no preview.
      There are a ton of plug-ins available for Visual Studio, but you can't filter for just the ones that will work for the web environment. Turns out, there aren't any that provide any sort of HTML preview. This makes working on a project difficult, I don't mind committing to see my changes, but I do need to be able to test them. Even that stack of punchcards gets you a printout, even if it's just a big old nope. I still have to get that committed JavaScript loaded into a web browser, which means loading it from web server.
      This stumped me for a bit, but then I discovered GitHub pages. All the documentation they have says "use Markdown" but it turns out, you can just set the project's document root to be the repository root. That means that if you have an example HTML file that loads a JavaScript file and some style sheets and whatnot, you now have a functioning edit-commit-wait-wait-reload-wait-reload-double-check-console-load-run loop.
      There's some waiting and reloading in there, because it took me awhile to be able to figure out how to even tell what version of the code is running in my browser. Safari doesn't have a developer console, so I use a plug-in. I think there might be some bugs in it. Anyway, if you look at the resources tab, you will see a version of the file. If you look at the network tab, you will see the version that got used. This may be one version behind the one that you see in the resources tab.
      Finally, I decided that I could, in fact, properly bind to a command key; determine if the shift key is down; split undo functionality into two methods; substitute my wrapper object for the bits that Concord uses for undo; add a list; and step through the list. It kind of does multiple undo, but weirdly. The cursor doesn't do what you'd expect. You couldn't possibly use it in real life. But it's literally a proof of two concepts: I can use GitHub as a development platform on an iPad, and it is theoretically possible to add some sort of multiple undo to Concord.
      I was going to stop here. However.... I can't stop reading the Concord source. I am learning that I should just go ahead and focus on the projects I just can't help but doing, and, apparently, for now, this stupid, quixotic, thing is it.
      This has been a quandary for me, because I've been promising to post some code on the blog, but now I don't want to post something that clearly isn't even working properly. This is the part where I learn to get over myself, and realize that nobody cares if I have a broken fork of Concord, and even if anybody is reading the posts down here, it still doesn't matter. In the end, there are dozens of forks of Concord, and this is just one more. And even if I never get it working, at least I've got something new to write about for a bit.
      It doesn't have to be perfect. It can be a work in progress. It is definitely a work in progress.
      ~
      The repository is on GitHub at PostMonsterG/concorddd. Here is a link to the page I've been using to test my changes. It is broken.
      This previous post goes into more detail about why I want multiple undo in Drummer.
      The Loaf Question documents, kind of, a previous exploration through someone else's code. Also the branching parallel universe thing, as it happens.
    Roady: What do we back up, and what do we call that thing?
      (4 min read)
      I'm mostly working on Blackjack right now (no, really), but I do have some plans for Roady coming up. The next major feature is going to be some sort of ability to restore a file from GitHub. They have a whole fancy website over there for navigating repository histories, so restore might be as simple as a dialog box where you paste in the URL for the version you want.
      Beyond that, the only other major feature left for Roady is the roadkit. When those two things are done, Roady will be done.
      Between then and now, I expect to rewrite and reformat Roady repeatedly, until it acts and reads the way I want it to. This post is about one of the little design decisions that go into that.
      One of the little features I am thinking of adding is the ability to exclude a file called prefs.json from backup scans. It looks like something Drummer uses to keep track of preferences and state, nothing fancy. It probably changes when I switch around between tabs, stuff like that.
      I don't really care what's in there. It changes often enough that it causes more commits than I'd like to my backups repository, though. Which is one reason why I'm thinking about providing a way to skip it during backup scans.
      However, there are actually better reasons to skip it:
        I can't restore it.
        I don't know what it is.
        I have no idea when it could be possibly be safe to write to it.
        I have no idea what restoring an old version of this file could do.
        Drummer is a networked application. I can't possibly know how client and server are intertwined.
        If Roady gets restoring a regular file wrong, you still have it in GitHub.
        If Roady gets this wrong, it could fuck your Drummer environment.
        There is no way to un-fuck your Drummer environment from outside Drummer.
      I think I have some good reasons to skip it, but: Roady does backup. What the hell kind of backup skips critical files?
      I think the answer might be in the name of the menu items for enabling and disabling this behavior, which just now finally clicked for me. I've been thinking about this for a couple days. Naming things in Roady is critical because I have a goal of never changing this sort of thing.
      One of my favorite quotes from Ted Nelson is, "Can you use it in the dark?" Part of that is, when the lights are out, it is just the same as it is when the lights are on, just fewer photons. Nothing changed, it didn't move on you.
      I hate when shit moves on me. It makes me think I'm losing my mind. I am pretty sure that is just getting old, and not the universe actually messing with me. But I do not know. It is disorienting, I hate it, and I bet you hate it, too.
      I intend to reduce human misery in the world, any way I can, and every single thing you fuck up for a user, is actually multiplied times every single user you have. That can add up to hours, months, years of misery. Because you thought the new menu item did most of what the old one did. You fucking asshole. I may have strong feelings about maintaining user expectations.
      So if I do add a pair of menu options to enable and disable this, what do I call them? I think it's only this one file. But maybe I'm wrong. Or maybe it changes. So I can't call it "Don't back up prefs.json" or even "Don't back up Drummer preferences".
      What just occurred to me is, as usual, obvious, so I feel dumb. But the answer is, something to do with user files versus Drummer files. I think I will probably go with user files, because I'm already referring to how Roady backs up, and uploads, your Drummer files.
      But that's the distinction, the in-or-out: is it the user's, or is it Drummer's? That, for me, nails it.
  January 8
    Roady, the README
      The other place to see what I mean, when I say that Roady is a self-contained statement about how software ought to be done, is the README. Eventually it'll probably get split out into something more manageable, or reorganized, or whatever. But right now, if you go to Roady's repository on GitHub, you'll see what I think ought to be the minimum standard for this sort of thing. Every single thing the software does, from a user's perspective, is described there, as plainly as I can put it. Even if you have no interest in Drummer, take a look to see what I am talking about here.
  January 7
    More about my goals for Roady
      (7 min read)
      This post is mostly a bunch of stuff I wrote on Twitter recently. I am finding I enjoy writing longer-form essays on Twitter, probably because it's got to be the stupidest use of Twitter I can think of. Why not write in a real editor?
      There's something, for me, about having an idea just burble at the back of my head while I'm doing something else, until it jumps up and says, "OK, type this now, it's good, move on."
      Then I can move on to the next thought I really, really want to get across. And when you're doing this on Twitter, you have to be careful about throwing around the "really, really"-type things. So once you pull it all into Drummer for cleanup, it's pretty tight, and ideally just needs some punctuation, etc.
      Roady adds features to Drummer to make it easier to work with GitHub. The key feature is continuous, automatic backup of your Drummer files to GitHub. This gives you the equivalent of a time machine for your outlines, complete with diffs.
      In a way, Roady is as much a piece of software as a self-contained statement about how I think software ought to be done.
      The 0.3.0 release is what nailed Roady for me. It is the minimum set of features you want in Roady.
      It protects you from any possible failure in Drummer, ignores useless updates, and lets you leverage GitHub for diffs and time travel, without having to use a full-on git client.
      My interest in Roady is purely practical. I want to get it done, so I can use it, and forget about it. I know exactly what features I want for version 1.0.0, and I don't ever want to reach version 1.0.1.
      My real interests are more along the lines of my recent post on Blackjack, if that gives an indication. (Also, as it happens, written on Twitter, over the course of several hours on New Years Eve.)
      I am particularly interested in using Drummer to maintain outlines that are translated into other formats, and sent to other services, through easily written, readable, and mantainiable Drumkit scripts.
      Things like ebooks and websites, generated from my own writing and web resources.
      Millions of pieces of content from the Smithsonian.
      Each with a persistent identifier.
      Content atoms are designed to be linked and compounded to make new types of data.
      Metadata format? Plain line-delimited JSON.
      Smithsonian Open Access - Registry of Open Data on AWS
      GitHub gives us permanent, forkable, discoverable IDs for documents and fragments.
      Drumkit lets us extract and manipulate and transform.
      Drummer gives us one place, which we can modify to suit our own individual needs, to tie all those things together.
      Some very interesting toys!
      Anyway, back to Roady.
      I only have the iPad. I think if I had access to a computer and local file system etc for this project, I would probably not have written Roady. For me, everything about Drummer is in the cloud. myfiles zip backups on an iPad are not really usable. Drummer lets me, well, fix Drummer.
      Roady goals—
        Semantic versioning
        No moving, deleting or renaming menu items
        No using undocumented API
        Least intrusive defaults
        Inline documentation
        Copy-paste install
        No modifying Drummer internal files
        No browser DOM tricks
        Readable, step-by-step, no-tricks code
      Semantic versioning means, if it’s a patch, it is safe, and recommended. If Roady changes behavior, or adds features (which is a change in behavior), it is a new version, and updating is optional.
      No moving, deleting or renaming menu items means, if a feature is there in one version of Roady, it will be there in the next version. It will do the same thing as before, possibly better.
      If it does something different, it will be a new menu item. Which also won’t move on you when you update.
      No undocumented APIs means, it is better to scan every file to see if its contents match the current tab, to determine the filename, rather than just grab it from Drummer’s internals somewhere.
      If the first breaks, it shouldn’t.
      If the second breaks, wtf were you expecting?
      Fortunately, I don’t need the workaround. Now Drummer has the verb I need to move ahead with features related to restoring backed up files.
      Without it, I would skip these features entirely, no matter how much I wanted them. (Or, use a supported workaround)
      Similar logic applies to how Get Latest Roady works.
      It could easily modify menu and scheduler files itself. But then Roady wouldn���t work like anything else in Drummer.
      More ways to break, more things to explain, more junk nobody has time for.
      Roady’s design is 90% me noping out of things.
      Inline documentation means, Roady is intended so that if you want to see how it works, or what it is doing, it is right there.
      And if it is broken, or doesn’t do what you want, everything you need to know how to fix it will be right there.
      Roady is a single OPML file, that you add to your Scripts menu.
      Right now the docs like README are external. By the time Roady reaches 1.0.0, it will still be a single OPML file, but it will be called a “roadkit”, and it will assemble things like README from menu item comments.
      I think I may mean everything, too.
      If we have them, I am not sure there is a reason anymore not to embed a series of blog posts about how the code works, or design goals, right in the code.
      It’s an outliner, collapse it. Cycles are cheap, who cares if we leave the comments in?
      Copy-paste install means, you add and remove Roady like anything else you could have made yourself.
      No developer tools. No installer. Nothing tricky.
      A regular person, sitting on a couch, with an iPad, should be able to make, and share, a Roady.
      By version 1.0.0, Roady will be distributed as a roadkit, an OPML file. There will be full docs for the roadkit format.
      It will include a customizable template for quickly making new roadkits for new apps, with basics like sw update.
      I think my next might be called Snarktown…
      My goal is to have the roadkit still be something you can just paste into your Scripts menu.
      I do not want to write an installer. I do not want to modify someone’s Drummer iconbar, scripts menu, root etc.
      I could easily make Roady load itself remotely at startup, like a rootkit.
      If you can’t walk someone through it, step by step, then the steps are too complicated.
      Roady doesn't, and won’t, do lots of things because I think requiring copy-pasting 3 items is too many.
      Roady installs with just 1. Two if you want automatic, continuous backups. 3 is too many.
      If you require 2 steps, then you can provide menu items like start-pause auto backups, and changing scan interval without editing the Scheduler.
      But then you are only using the scheduler to poll a work queue, and your code is suddenly different from how Drummer normally works.
      Requiring 3 copy-pastes is too many. If you do, it’s because you want to put some code in root, or at startup.
      This is the way you “should” do it, because then you can share code between scheduler items, menu items, etc.
      But now it won’t work without 2 steps, more chances to fail.
      No DOM tricks means, do not extract or insert structure.
      If you can’t get the data through a supported API, you can’t get it.
      If you can’t represent data using the provided API, try harder.
      Roady will not invent new dialog box types, or dynamic menu enabling, or iconbar swapping.
      Readable, step-by-step, no-tricks code—With license, comments, software update, preferences, links to help and the latest version, Roady 0.3.0 is 524 lines of code.
      Without blank lines, comments and documentation, all of Roady fits in 270 lines of code, as plainly written, and easy-to-follow, as I can possibly make.
      I’ve spent a LOT of time thinking about how to structure something like Roady in Drummer, months, actually.
      But all of Roady has been written over just the past few evenings, on an iPad.
      Drummer has raised the bar for making and sharing new internet things.
    You cannot stop this one-tweet manifesto about my goals for Roady
      Roady goals���
        Semantic versioning
        No moving, deleting or renaming menu items
        No using undocumented API
        Least intrusive defaults
        Inline documentation
        Copy-paste install
        No modifying Drummer internal files
        No browser DOM tricks
        Readable, step-by-step, no-tricks code
    One more manifesto, in single-tweet form
      GitHub gives us permanent, forkable, discoverable IDs for documents and fragments.
      Drumkit lets us extract and manipulate and transform.
      Drummer gives us one place, which we can modify to suit our own individual needs, to tie all those things together.
      Some very interesting toys!
    Another one-tweet manifesto
      I am particularly interested in using Drummer to maintain outlines that are translated into other formats, and sent to other services, through easily written, readable, and mantainable Drumkit scripts. Things like ebooks and websites, generated from my own writing and web resources.
  January 6
    Hello, Roady!
      (1 min read)
      This week, I've been working on Roady.
      This week, I've been working on Roady.
      Roady adds features to Drummer to make it easier to work with GitHub. The key feature is continuous, automatic backup of your Drummer files to GitHub. This gives you the equivalent of a time machine for your outlines, complete with diffs.
      You can also upload individual Drummer files to GitHub, which can be useful for sharing your outlines with others. (I use Roady to post new versions of Roady on GitHub.)
      Roady is currently at version 0.3.0.
      I have a few more releases planned. I intend to write more about Roady. I am having a blast.
  January 5
    🪀 🐕
  January 3
    Hello, Blackjack!
      (7 min read)
      I am going to design a programming language where everything is an NFT.
      The brace is an NFT, if–then is an NFT, looping and blocks and scoping are also NFTs.
      Everything, including variable values are actually pure functions, which are also NFTs.
      Also, you can fork the brace.
      It will target a Harvard architecture virtual CPU, with a write-once model for the data side.
      CPU definition, register hardware, each bus, memory cells, all NFTs, all forkable.
      Each CPU instruction cycle, bus context, inputs, results, all NFTs. Forever referencable & forkable.
      Rather than proof-of-work, entity (commit) IDs will be verified through genetic algorithms (competition in defined realms).
      That is, the brace everyone uses will be proven to be the correct one through fitness, in an environment, rather than simple obscurity.
      The tests, NFTs
      Function inputs are convoluted from nearby context, remapped through (forkable, overridable, themselves convolutable) function/entity references.
      This holds for every entity in the system, the language definitions, the implementations, the virtual CPU model, cell/register values
      Each fact in the system is a unique thing which can be referenced and transformed.
      And can define the types—the boundaries—of the transformations allowed before it must be regarded as a different thing.
      This is a spectrum of differentiation, a classification function, mappable
      You can fork the core fact of the universe, and spin up an entire parallel system, all based around that single variant ID.
      Each ID in the new universe is a pointer to its original, in the source universe. The new context can be overridden, as needed, by applying transformations
      Or, the old universe is projected through a mapping. That projection is the new context
      The old universe is also a projection, an applied mapping, from the new universe.
      Causality propagates through a context similar to Wolfram’s cellular automata. This is the speed of reality
      Because everything is immutable, causality graphs are reversible. Time travel—undo—is just another mapping from one context to another
      Execution is a continual transformation of the context from one state to the next
      “Next” should prob be thought of as a cloud of states, though
      Every process runs in the same shared context.
      I don’t mean, every process on your computer, or every process on this VM, or every process forked by this code, or every branch taken speculatively in parallel for this VM cycle.
      I mean, EVERY process. Everywhere. Every invocation
      Every process runs in its own context. Every process.
      Every single branch speculatively executed happens in its own unique, identifiable, permanently referenceable, forever forkable, context—a parallel universe.
      The mapping, between the global context and that, is what you code
      The system bootstraps, essentially, from the original fact.
      This fact is one bit, that there is something, rather than nothing.
      Everything else is transformations applied to that fact, to create a new context.
      Mappings which Gödel up best they can, of course. Can’t escape math
      Once you’ve defined a system like this, you don’t have to actually build each of the conceptual layers.
      You can assume exists the Harvard CPU that tries out branches by spinning up a whole new VM, without it needing to exist.
      You just need to know how it must be, if it did.
      That original fact, that there is something, rather than nothing? NFT
      In this language, there is literally one root to the entire thing, one single root to every piece of code, context, data, transformation, that exists.
      That can even be expressed
      There is literally only one 1
      How about the opposite fact? We can’t have true without false.
      Well, false is a mapping applied to true. It��s the opposite of true! Except that’s trivial, we will run out of steam on that concept when we want to count past two.
      (Once we even know what two is. What even is two?)
      Traditionally, when working with a system like this���these are not new ideas—you’ll conceptualize it as a transformation. An applied pure function.
      A “black box,” inner workings uninteresting and unknowable, which takes “true” and returns “false.”
      This can be super useful
      Mapping functions and black boxes are not the only way to reason about these self-referential systems
      You can also think in terms of boundaries. There is true, and not-true. There is true territory, and outside that territory, it is not-true territory
      Between them, the boundary
      The boundary defines the space, it is the same as the mapping function, the convolution, the transform. It has just been transformed itself, remapped into another domain.
      This is the same as doing a fast Fourier transform to convert periodic voltage measurements into frequencies
      The boundary between one state, with all its inherent context—which, in this system, is literally everything in the system—can be complex, to say the least.
      But you can distill it down to a distinction: in, or out.
      This can be useful when working with tree-like structures
      The ability to easily define these boundaries, these in-or-out conditions, is a critical feature in the design and structure of the language.
      That is, being able to express, and work with, the concept of “this, but with these differences.”
      It���s basically the key feature, really
      The whole point of this horrific NFT language design is to be able to fork reality. To express, and work with, the very idea of “this, but with this difference.”
      This brings me to the name of this new programming language:
      Blackjack
      Let’s lay down some ground rules for Blackjack. This isn’t Calvinball. While the end result of a run of Blackjack may end up indistinguishable, at the bottom we are going to agree on some things.
      Everything is an NFT
      The fundamental data structure is a tree
      A non-fungible token is basically a key into the stupidest key-value store there is. It is not like memcached, where you know where your data is, and can retrieve it, say, upon request
      NFTs are that, except all you get is the key.
      You still have to negotiate key→data elsewhere
      In Blackjack, you are guaranteed that your NFT will always return the same set of bytes. Assume this is magic.
      What is at those bytes, is trees. Trees of NFTs
      So your NFT is a pointer, a handle, a symbol, which forever represents this tree of NFTs which can never, ever change
      As Java is built on the JVM but we usually don’t talk about that level, rest assured that in Blackjack it really is NFTs all the way down
      You can assume there is an NFT for true, and every other NFT is defined in terms of that; its negation; and lists of one or the other—10110…
      Blackjack has some rules. Your NFTs are arranged in trees, and each node points at a tree. These are simple trees, either there is an ordered list of children, or not.
      Each reference, however, requires two NFTs. The first points to the tree you are referencing. The 2nd is a map
      The map defines how to transform what is at the first link when including it. The simplest transformation is to just include it without transforming, of course
      Transformations are defined by series of node operations. There are fundamentals like iterate, conditionally insert/del
      So you’re typically traversing a node structure, and constructing a new node structure that��s a transformation of the first somehow, generally based on things you can extract from the first. Again, these are simple trees all the way down, but at this level, nodes have attributes
      That is, if this node has this attribute then perform these transformations, etc. We’re not savages, this isn’t brainfuck. You’re not writing AGCCAT-level op codes.
      You can drill down to there, and fork them, though. That’s how Blackjack rolls, that is the Blackjack jam.
      During execution, Blackjack maintains a lookup context for resolving references. This of course is a scoping tree, with applied transformations, like everything else. Most of the NFTs in Blackjack are anonymous. Parameters are optional, and positional, like JavaScript.
      Blackjack has semantic versioning for NFTs, with simple discovery for things like “does a fork of this NFT exist in this particular universe, with compatible or transformable inputs and outputs”. You can put a wrapper on it. You can swap it out.
      Blackjack trees are, at the API level, generally very flat. A list of arguments. An argument might be a list of lists. Think keypaths like list, item.key.subkey, etc. Most naming resolution is implicit, with the usual ancestor lookup process you’d expect (with mapping of course)
      Input and output trees are of course arbitrarily complex
      A typical use case for Blackjack would be transforming a large JSON or XML structure into another form such as a website, or closed captioning; or creating a directors cut from an EDL; or a fan edit of that directors cut
      Anyway, I’ve decided to build my own Blackjack, with OPML, Drumkit, and GitHub—
      I am so pleased with myself. This is the best project ever. It is so incredibly stupid.
      But now I have to do this. Because when I am done, I will be able to say,
      “Yeah, well, I’m gonna go build my own app… with Blackjack!”
      This is what life is for.
      I designed this on Twitter on New Years Eve.
December 2021
  December 30
    Look I made a thing: Backup All My Files to GitHub
      I am extremely, extremely pleased with myself at the moment: I am now using GitHub for my Drummer backups. And that means I get diffs.
      I made a few new menu items for Drummer tonight. And, thanks to some menu items I made previously, it took me about 30 seconds to publish them on GitHub for everyone else to use. Here they are—
        Configure GitHub User Name
        Configure GitHub Backups Repository
        Configure GitHub Backups Path
        Backup All My Files to GitHub
      Now, back to horsing around...
    Drummer ate my new website templating language
      The outline shown in the previous post no longer exists. Several things have just failed here:
      Drummer's warning about having another copy open is welcome, but possibly insufficient. Closing the other copy of Drummer may have been what screwed me.
      The outline shown in the previous post was only a portion of a larger outline, which I generally work with pinned. That section of the larger outline is what has vanished, not the entire file.
      My latest backup, taken contemporaneously with the vanishing, does not contain the vanished portion of the file.
      The 15 backups previous to that, between 6:57 p.m. and 10:56 p.m., all show as incomplete downloads. I do these backups manually, but I wait until Safari gives me the "Do you want to download myfiles.zip?" dialog box, and hit the Download button before putting the iPad to sleep. Sometimes it can take a minute before that dialog shows after I select Download My Files, but I can be patient. I have taken a few backups while writing this post, and each shows as incomplete, though Safari has given me the little icon bounce that usually indicates a finished download.
      I'm not upset, really. I am so fucking glad I took a picture, I cannot tell you. But it's all work I can re-do. The approach I am taking to solve the templating problem is obvious, so it will be super easy to recreate my prototype template.
      And Drummer didn't eat the part of the outline that contains the website that feeds into that template, either...
  December 29
    Sketching out a new website templating language
      I'm just about to wrap up work on a project you can see a glimpse of in my previous video, but I wanted to take the evening off and work on something different. So I decided to invent a new website templating language, serialized in OPML, implemented in Drumkit. Proof-of-concept is Bootstrap's carousel demo. This is the prototype template. Italics are substitutions. Cap italics are lists. Supports localization. Data input is OPML.
      I'm still working through the details, but I like how it looks so far.
  December 28
    Speaking of literate coding, sharing and remixing
      I posted a video to Twitter documenting how I use my new Save File to GitHub menu item to share my Drumkit samples for everyone else to use—or better yet, remix into something new.
    One-tweet manifesto
      Agreed, that’s why I am spending so much time on trying to find the simplest idioms for my Drumkit code; instructions right in the OPML file itself for installing and using; stupid amounts of docs; and GitHub. Drummer has unique options for literate coding, sharing and remixing.
      Posted in reply to this tweet by @RonKJeffries
  December 27
    The simplest tools
      After putting up the drumkit-samples repository, I realized I hadn't actually posted the code for the Get My Latest Twitter Rant script. Fortunately, this is now easily rectified.
      I opened up my scripts menu in Drummer, and copied the version of the script I'm using. Then I pasted that back into the file I've been meaning to post somewhere. Now, I just had to add some new headers to my file. I used Drummer's Edit OPML Headers... command to set rd-repository to "drumkit-samples", rd-path to "GetMyLatestTwitterRant/GetMyLatestTwitterRant.opml", and rd-type to "opml". Then, I selected my new Save File to GitHub menu item, and there it is.
      Now I can go back to working on the reason all those attributes have names that start with "rd"...
      Previously about Get My Latest Twitter Rant.
    Look I made a thing: drumkit-samples
      There are a lot of stupid reasons that I haven't posted any of my Drumkit code—it looks bad anywhere but inside Drummer; the usual dumb personal life reasons; getting caught up in a really stupid side project; so, so many more—but the stupidest of all has got to be picking a name for the GitHub repository. I have spent weeks thinking about this. I am serious. Well, here it is: drumkit-samples
      I like it because it's not weird. It's sample code, everybody has a samples repository. But really, I came across this name from the other direction. When I came up with the name "Drumkit," I was thinking about musical things, because, Drummer. I wanted a name for the repository that also came from music, and ideally, percussion. One of the best tools for this sort of thing is the big print edition of the Sweetwater ProGear catalog. I guess a musical dictionary or something would work better, but this is what I have.
      There are a lot of words related to percussion, and equipment, and racking, and beating, and thumping, and pedaling, and a whole bunch of fun instrument names like congas and marimbas and bongos. Those are just plain fun to say, and they are drum-related, but they do not mean what I want the name to mean. Part of where drumming has been going, for the past forty years or so, has been digital. The Sweetwater catalog is great fun to paw through and look at, and they have some really nice-looking drum sets in there. And some look crazy, little flat pads instead of big resonant chambers. Those are the digital drums, and the things they play are called samples.
      Sampling is a huge, huge, huge part of human culture, we could not have a society or art or language without it. We take things that others create, we take bits of them, we take those bits, those samples, and we recombine them back into something new, something that could have never existed before.
      And that's exactly what I wanted to convey for this repository. These are little bits of Drumkit code, little snippets, little samples, for everyone else to use, and remix, and make into something new. I dunno if anybody will, but at least I got the name right.
      The drumkit-samples repository is on GitHub. The best parts so far are the DocServer Lookup icon, and the Save File to GitHub menu item.
  December 19
    Undo
      (8 min read)
      I've written previously about how great Drummer is, and the parts that bug me. Right now, there are only two things that really bug me: Occasionally, Drummer will overwrite the contents of a file with another. And, Drummer's outliner needs multiple undo.
      Dave's working on the first issue—he's had it happen himself, now, so he's in a position to track it down. And I've provided as much detail as I can, here, and on GitHub. I never did get it nailed down to specific, reproducible steps, but sometimes anecdotes are all we have to go on. Backups are a good thing to have, anyway. Think I'll make one right now.
      The second issue, multiple undo, however, is another matter. It is a request for a new feature, not a bug fix, and one that can't easily be justified. "But I neeeeeed it," works just as well as in this case as when my kiddo is explaining his Lego requirements. In fact, it's a completely unreasonable ask, and I am not being snarky when I say that. Drummer's outliner is Concord, and its codebase dates back decades. Here's the first part of the README:
        Concord is a JavaScript outliner written by Kyle Shank in 2013, maintained by Dave Winer since, GPL-licensed.
        The user interface is keystroke and mouse-compatible with the Living Videotext outliners, ThinkTank, Ready and MORE, and the outliner built into UserLand Frontier and Radio UserLand.
      Those Living Videotext outliners came out in the 1980s. This is what we call a mature codebase. You do not just go in and start mucking about. And the thing I want, multiple undo? That goes literally to the heart of what an application does.
      What does code do? It does things. If you are careful, you can design it so it also undoes things. But that, right there, is already twice the work. Because doing things is easy. If you think undoing things is also easy, you have never, ever, wanted an undo button in real life, and I would like to meet you, for you are not from this planet.
      Nothing in software is actually reversible. There is no library function that will undo the results of another function call. There is no processor instruction, like ADD or MOV, called UNDO, which will reverse what just happened. You can, sometimes, use another instruction that will do the equivalent of an undo. Maybe that instruction that moved the value of that register into memory has a variant form that lets you reverse the source and destination bus. Usually it's a completely different instruction, though, a load or store. Why would you need an instruction that just undoes what the last instruction did, anyway? You never would. What you want to undo is much, much bigger than the results of a single instruction.
      By the time you're working at the level of something like Concord, the number of instructions involved in making any change is astronomical.
      Concord is part of a history of outliner code that goes back to the 1980s—see this page for some of that history. I doubt that any of its code actually dates back that far, but its user interface, and the understanding of the nature of outliners, as embodied, dates to then.
      My iPad has a M1 processor, and a quick Google indicates it's rated at multiple teraflops. If you started with computers when I did, that is a mind boggling statistic. Nowadays, it's merely impressive, for a mobile device.
      A flop is a floating-point operation. For an 8-bit computer, like the Apple II or the TRS-80, one flop is a lot of regular operations. Those processors were clocked in the millions of operations per second. So those ancient computers could load or store that register, do that MOV or ADD operation, a million times in a second. Think about it, that is actually a lot of work. You have to move a lot of data around to make a computer program work, because each time the processor goes to the next instruction, that is also an operation.
      Text can be thought of as a stream of characters, and at the time, one byte = one character. (Images require a thousand times the data that text does, and video a thousand times that.) So you can move a million characters a second. But floating-point numbers are bigger than characters, they are several times bigger than characters. You can't just add them, either, every single fiddly thing a computer does is buried right there, it takes a ton of operations just to add two of these things. And 8-bit computers don't know how to divide numbers (some don't even know how to multiply), and definitely not numbers that span several bytes. So, a flop, a floating-point operation, is actually a whole bunch of even lower-level operations.
      The Apple II, which ran one of the ancestors of Concord, would probably be rated in maybe hundreds of flops per second. My iPad is rated in trillions.
      If there isn't an undo library function, or undo instruction in a computer, then how can you have an undo feature at all? One approach is to build your own, with blackjack. As long as you understand what your code is doing, you can undo it. Code performs transformations on data. An undo is simply another kind of transformation.
      The difficulty is that the underlying data structures are never what you see on the screen. You are never looking at a linked list, or a circular buffer, or a stack. You're looking at a carefully maintained virtuality. When you're typing new text into the middle of a document, it looks like the words are being inserted and the rest are being moved down the page to make room. This is a fake, like a movie. If you did it that way, the computer would just spend all its time shuffling bytes through memory.
      Instead, you have a fiendishly complex system of buffers and pointers, and you're moving as few bytes as possible. And in ways that, even if you're looking right at the code that does it, with comments that explain how it works, can be completely opaque without hours of careful contemplation, until you get the data structure in your head.
      Then, you just add undo. Pretty easy, really. To undo making a sandwich, you just do all the steps backward.
      Here's the best part about working with computers, and magic, and movies: You get to cheat. You have to cheat! There is no way you are sawing that assistant in half. Those explosions are not real. Those words are not being moved smoothly down the screen. Everything is a lie. Everything is a fake. So how can we fake having an undo function?
      You take advantage of another thing that is great about working with computers: You can make copies. You can't do this in real life. You do not get a backup car. You do not get to make extra copies of anything, anywhere, in any situation. Ever. The best possible way the universe has come up with to make a copy of an object is life, and that takes time. You can grow a new plant. It will be "identical". It will not be a copy. You cannot replace one plant with another, they are two separate things. This is inviolable. This is fundamental to reality.
      But in a computer, you can actually make an actual copy of something, because it's a series of facts—a series of the simplest possible fact, actually, "Yes? Or no?", over and over—rather than an actual thing. A fact exists outside reality. It is a completely separate thing, it is a truth which can exist whether or not it is tied to a reality at all. This is what computers give us, a tool to discover, and manipulate, things that exist outside reality. This is a kind of power that we are literally at the dawn of discovering what that even means, by the way. We have no fucking idea what is coming.
      In fact, with a computer, you can carve off entire universes, and duplicate them. We call this saving state. Depending on how much memory you have available, this state can be as big as you like. In fact, if you are OK with limiting your documents to half the available memory, you can get undo by simply making a backup copy of the entire document before doing anything to it. If you don't provide undo at all, your users might actually just do this step themselves, but it'll be slower, because they'll be saving it to disk.
      On an Apple II, you would never, ever, do it this way, because you only have 48K of RAM available in the first place, and persisting things to disk takes, like, forever. But you don't have to save the entire document. Remember, you've got this fiendish array of buffers and pointers and whatnot. So you can make a copy of one or more of those things. Even this is complicated, because those data structures are complicated, and interact in non-obvious ways. But if you're careful, you can make it work. You can get it so the user can do something arbitrarily destructive to a document, like adding or deleting text, or indenting a node, or moving a node from one place to another, and then that thing can be undone. Of course, now you have to let the user re-do what they undid....
      This is a huge fucking accomplishment, I cannot tell you how much work that kind of thing can be. It is so much of an accomplishment, that there was a time before undo was a thing. Every single feature we now take for granted, like being able to talk to a computer, and have it talk back, was originally something that was Brand New, and mentioned prominently in advertising, and documentation, and discussion.
      And at one time, undo was brand new, and amazing. I hope I've given some indication of just why.
  December 14
    One reason I don't post code
      I have not yet figured out how to post Drumkit, in an OPML file, as it appears in Drummer.
      So I post screenshots, and one-minute videos to Twitter. I will post things to GitHub, with fancy markdown readme files. But anything in Drumkit, anything that's an Opml file, is going to look terrible. I don't have any suggestions for how to fix that, actually.
      It's a shame, because Drumkit looks awesome inside Drummer. That's why I post screenshots and videos. I get really excited, because for the first time in a very, very long time, I get to control everything about how my code looks and works—there's an insight lurking there, somewhere—and the whole experience is very cool. Coding in an outliner is not actually like being able to collapse things in an IDE.
      Anyway, for now, I will continue to post the videos, and when I start putting things on GitHub, they'll have markdown readme files, at least. (Maybe some sort of Drumkit-to-markdown converter, just for viewing? I really have no good suggestions here.)
    Where is all the code and things?
      I have had every intention of posting actual running code for things I've talked about, and things I haven't, for day after day after day. Well, tomorrow's the day! I have no real reason for saying that, more than any other day recently. I work on this stuff in the evening, and weekends, and my days off, and sometimes during lunch. I'm taking tomorrow off, and I'm going to work on this stuff some more. And maybe I'll get something done. Maybe I won't. But either way, I'm posting something. There, now I have to. And whether I get it working or not, I need to just get over myself, and my need to always fix everything before it can be shown.
      It may only be some documentation, but I'm going to post something. Nobody cares as much as I do, and it's not like anybody's going to steal my brilliant ideas, or something. Sheesh. This is a lesson that the blog part keeps teaching me. I should just listen.
  December 12
    Daytona gets some verbs
      I'm working on something else right now, which I hope to post later today.
      But I wanted to note that Dave has added some Daytona-related verbs to Drummer. This was the one thing I felt Daytona was missing. I didn't want to say anything about it in my previous post about Daytona, because a) I've been saying too much lately about things I think Drummer is missing, and b) I was pretty sure these verbs were coming anyway, because that is how Dave rolls. What's the point in making a feature like Daytona and not giving us a way to use it in Drumkit scripts? Right, nothing.
      Drummer continues to be fucking awesome.
  December 10
    Hosting and statutory licensing
      Everybody is all, “host random node app,” or “use my blogging service,” or “you get to maintain your own security in this web server also there is a database good luck.”
      What if it was, “host this OPML, this template, and these images, at this domain name”? I’d pay for that.
      I’d pay for hosting my podcasts episodes, too. If I had any.
      But I’d pay anyone but Google to host my little Drumkit videos at anyplace that isn��t YouTube, that doesn��t put ads or comments or upvotes all over that shit. And won’t go out of business next week. That’s important
      And why would I need to pay that much, even without ads?
      Why isn’t there statutory licensing for our videos and blogs?
      Why can radio stations play whatever song they like, and the artists still get paid?
      Why isn��t internet hosting like that?
      I wrote this teeny non-rant on Twitter, and then posted it here, using a little piece of Drumkit that is seeing surprisingly more use than I'd anticipated.
  December 9
    A quick spin around Daytona
      I checked the Change notes outline in Drummer's Docs menu, and boom! Dave Winer has released a new indexer for OPML files, which he calls Daytona. Here are some quick thoughts, after reading the docs, playing with it for a minute, and listening to notes linked in the docs—
      I love specific search things like this. Everybody laid down and let Google do their thing, and just kind of forgot the idea of doing anything but using Google. If you know something about the structure of your data, you can do a far, far better job, every time.
      For instance, search engines think of everything as a web page with a URL. Guess what, everything on that page probably has an individual, addressable unit. For example, a list of threads on a forum page. Or a list of posts on a message board thread. Or, a blog post on a calendar-based page. Or, an individual node in an OPML file...
      Daytona indexes public Drummer files, the Drummer documentation, and Dave's website. See the docs for details. You can follow the link above to try it out, but the real magic happens if you have a Drummer account. When you click the eyeball icon, it switches to Drummer, opens the outline in a tab, and goes to the post. I mean, it expands the outline heading and goes there.
      You don't have to sign into Daytona and search your own blog for this. It might actually be more impressive when you're searching Dave's blog. Because the OPML files being indexed are Dave's public outlines—which he uses to create his blog pages—you can open them right in Drummer with that eyeball button. You are working with an outline. This is cool, and the way searching should be.
      This is better than just a list of search results, because it ties the actual thing being indexed, the entry in the OPML, to the entry in the search index, in such a way that you can get back to the original document. The original data, in the original place, not how it got rendered onto an HTML page at some URL.
      One thing I am curious about is how IDs are being assigned to the items in the index. Does a blog entry get a new ID when it's moved into an archive outline? It's at a new location. It's got the same content. Is it the same post, or a different post, at that point? These are hard questions, ones that I've written about before, and will again, here on the blog part.
    OK, Drummer ate my blog again
      Fortunately, I have been saving backups. It turns out that backup 197, saved at 5:54 p.m., December 8, contained my blog. Backup 198, saved at 5:57 p.m., December 8, contained the contents of another file. I'm currently at backup 229. Well, 230. So I had to go back almost three dozen backups to recover my file.
      Good thing this is not my first time around this particular goat rodeo. But it is tiresome. You have to reset each OPML header individually. And now I am wondering about what other files may have been missing for the past day that I don't know about yet.
  December 7
    Twitter rant: NFTs and video games
      I hadn't expected to put my new Get My Latest Twitter Rant script to use again quite so soon, but here we are. I ran across this article on Medium, and before I'd even read it, I was ticked at the very notion of a video game making use of NFTs.
      I love stupid ideas, but of all the stupid fucking ideas I’ve heard lately, making a game that uses NFT or blockchain in any way has got to be not only stupid, but monstrously evil. Like, “we make ricin for kids”-level evil
      NFTs in video games can only exist in a game targeted at whales. This is like a casino you carry with you everywhere you go. These whales are not rich people. These are no different from heroin or any other addiction. You are stealing their lives and leaving them misery
      But not only are you ruining lives just for your own sake, you are churning carbon into heat even faster than ordinary bitcoin. To base a game on NFT you are creating a fountain of assets, each scorchingly costly to the rest of us, for your own sake
      Anyone who would create or profit from a game based on NFTs is a fucking asshole
      The very idea of suggesting an NFT game should cause derision and scorn toward those who suggest such a thing. These are the sorts of people who would sell literally anything to anyone, no matter how dangerous, without even thinking or caring. Only shame & mockery can stop them
      I work for a game company, I make my living from completely frivolous products no one really “needs”. But we do need entertainment. What we do not need is entertainment that costs literal human misery. Anyone who cannot see that does not understand what it is to be human, just $$
      I am sick to fucking death of all these fucking assholes who think that just because it is not against the law then it is their sacred holy duty to extract every fucking dollar they can from any opportunity, no matter how shameful or the direct cost to actual humans, one or many
      If your cute little game makes all its profits from whales, you are a fucking asshole. There are only two kinds of people involved with NFTs: the victims, and the fucking assholes.
      Satoshi is anonymous because they are ashamed at what they have done. And if they are not ashamed, they should be
      In a few million years, the raccoons that survive us are going to reach the center of the galaxy, and discover why the Fermi equation works out the way it does: blockchain
      I guess externalizing all your costs on the rest of society is where it is at now. And here I am giving a shit about other humans like a sucker
      It’s like, let’s take one thing that profits from human misery, which is gambling, casinos, and draining whales, and then add something that will help ruin the fucking planet for everyone else, AND we get to profit personally?
      WHAT KIND OF ASSHOLE THINKS LIKE THAT??
      I guess maybe we could add handguns. That’s it: a video game where you trade NFTs and you can cash them in for real-life murder toys like tactical rifles and accessories and ammunition. OK, that’s probably evil enough for the moment. Now to secure funding
      Ok my video game where you trade NFTs for handguns is going to make me rich, and fuck all the rest of you. You are all such fucking idiots for educating me, providing me clean water and safe roads and parks. I am going to shit all over the rest of you for my own gain. Suckers
      Blockchain is a grift. NFTs are a grift. I am a firm believer in the value of grift—I am teaching my son to deal Three Card Monte so he can have something to fall back on. Not kidding, actually. But a card game on a milk crate isn’t going to destroy lives or wreck the planet
      Most people who think they are going to profit from one NFT scam or another are just being taken advantage of. You can see it in boardrooms with Bitcoin, everybody wants it and no one understands it. Execs get taken for a ride by common grifters with words like “non-fungible”
      I just realized I need to make the NFTs in my video game an actual crypto currency. One that is tied to a real world standard: The handgun standard. Your game rewards will be priced in, and exchangeable for, weapons AND groceries. (Protip: if u have weapons u don’t have to pay)
      NFT games are evil: 1) You’ll make 90% of profits from 5% of players, who will ruin themselves to do it 2) You are turning carbon into heat and can't even say "we are doing this because currency is a basic human thing", you are setting entire forests on fire for each tulip bulb
      Sponsored by Waste Heat, coming this fall to Netflix. Don't miss the Guncuddlers rant.
  December 6
    Drumkit state machine doodle
      I tossed off a comment recently to the effect that state machines should be considered essential. And that got me to thinking about what a state machine for Drummer might look like.
      I don't have any code to go with this, it's just a doodle, but I guess you could consider it the equivalent of a thing you could attach to a particular kind of node in a Drummer outline. You'd probably have different state machines for different kinds of nodes.
      For this state machine doodle, the idea is that transitions in node state could trigger little bits of Drumkit.
      (This is what I mean when I say, in Drummer, the outline is your user interface. You can see a little of this idea in my DocServer Lookup v7 demo video. We use the outline itself to present information.)
      Node states
        Expanded
          Collapsed
            dialog.alert( "it was open now we closed it" )
        Collapsed
          Expanded
            dialog.alert( "it was closed now it is open" )
        Comment
          No comment
            dialog.alert( "you uncommented the node" )
          Collapsed
            Expanded
              dialog.alert( "you opened this commented node" )
      In this example, we display an alert when you collapse or expand a node. We display an alert when you uncomment a node, but not when you comment it. And we display a special alert when you expand a commented node. This would override the other alert.
      I'll have to think about this a bit more, but I have a feeling this isn't something I can add to Drummer myself. Not in response to outline edits like expansion/collapse state changes, anyway.
      But I kind of like it as a way to represent a state machine for other purposes in Drumkit. Outlines are cool.
  December 5
    Look I made a thing: Using Drummer to turn my latest Twitter rant into a blog post
      Here's a quick video that shows how I customized Drummer to turn my latest Twitter rant into a blog post in just 15 seconds.
      Here's the transcript:
      Drummer makes it super easy to write new blog posts—you just hit the plus button, and start typing.
      Let's take one minute with Drumkit, and watch me turn my latest Twitter rant into a blog post in just 15 seconds.
      Last night I wrote a whole bunch of posts on Twitter. I was ticked. Time to turn those tweets into a blog post.
      Drummer has a built-in command to get my tweets for me, but it doesn't do exactly what I want. So after I posted my rant, I made my own command, in Drumkit. And now it's in my scripts menu.
      Not much code there at all. We grab my recent tweets, and reverse the order. Check the date for just the most recent. Clean the text. Insert it into the outline.
      OK, running out of time. Here goes, Twitter rant to blog post in 15 seconds.
      I add a new post. Give it a title. Run the command I wrote myself. Delete a couple tweets. And then we publish it.
      Refresh the page, and there it is.
      If Drummer doesn't do what you want, try writing some Drumkit!
  December 4
    Guncuddlers
      If you use a gun in America to murder people, you become a hero to the guncuddlers, just like Kyle. These parents will be lauded by you fucking assholes, just so you can keep your toys. You fucking assholes.
      If you like your guns, and you think I am wrong to lump you in with other gun owners, because you are careful, you are also a fucking asshole. Your fantasies about murder and control are tearing our country apart. You fucking asshole.
      Shame is the only tool we have left. They are quite clear that they will kill us all just to keep their precious guns. Those fucking guncuddlers. Those fucking, fucking assholes.
      Shame on you all for valuing your hobby over everyone else. Shame.
      Congratulations, guncuddlers, your hopes and prayers have once again been answered. Your great god of denial and control over people through the threat of murder will sleep deeply tonight. Tomorrow is another day, o god of guns and death.
      It is so tragic that a few children must be slaughtered to maintain our freedoms. Just because we can’t schedule the sacrifices in a calendar, doesn’t mean we know how many must occur.
      Day after day.
      Year after year.
      School after school.
      You fucking, fucking, assholes.
      It is time the rest of us stopped listening to the “responsible” guncuddlers. Every single thing they have proposed so far has only made the problem worse. MORE CHILDREN MURDERED BY GUNS.
      You fucking assholes. YOU are the problem. You should be ashamed of your fucking hobby.
      No guncuddler will ever give up a single gun in the name of anyone else’s safety, because one day, they will get to use it and finally feel the power of murder as a tool for controlling reality. You fucking, fucking assholes. WHAT THE FUCK IS WRONG WITH YOU
      It pisses them off even to suggest their hobby is murder, dreaming of murder, planning for murder, hoping for murder. It��s about their freedoms, they will say. Their freedoms to murder, as many as possible, anytime, anywhere. You fucking assholes.
      You can’t say anything bad about guns, because some guncuddlers are insane, and will kill you for speaking against their toys. The rest look on, and approve, because it keeps the rest of us properly afraid of their ability to kill us if they want to. You fucking, fucking assholes.
      Guncuddlers are the biggest fucking cowards in the universe. They’d rather keep their ability to murder at will than do anything to stop the CONSTANT, RELENTLESS, NEEDLESS SLAUGHTER OF OUR CHILDREN. You fucking, fucking assholes.
      Every gun can be stolen. Every bullet intended for use at the range can murder a child, on purpose, or by accident.
      No matter how careful you are, your toys are exquisitely designed solely to murder.
      To stop a heart from beating.
      To cause mourning.
      Every life taken with the toys you claim are for your freedoms, every single one is despair and mourning and screams of anger at your personal, fucking god. Good job guncuddlers, your hobby is fucking awesome.
      Thanks for saving our freedoms and misery, you fucking, fucking assholes.
      There is literally no way anyone with a gun, including you, can prevent a guncuddler from just up and murdering, anytime, anywhere, any social situation, any school, any restaurant, any office, any parking lot, any grocery store.
      You cannot stop them fast enough. Some will die.
      Your gun will not save lives. It is just one part of an enormous, monstrous, horrific, satanic, evil, offensive, disgusting, putrid, stinking, murdering, foul, jealous, controlling, sick machine, targeted at every human, waiting for a chance to kill.
      The thrill you feel at the range will not bring you the control and power you crave. It will only bring mourning and misery, death and weeping. Fuck you, you fucking guncuddlers for valuing that lie the weapon tells you, over the screams of all your god’s victims and their families.
      And the only thing guncuddlers ever fall back on is threats. “You can pry my magic metal cock from my cold dead hands” and “come and take it.”
      Jesus fucking Christ, you fucking assholes. All you can think of is finally getting to use that weapon. You fucking assholes.
      Fuck it. Ban every single assault rifle and concealable handgun. You can have one rifle or shotgun, kept in a safe in a licensed, certified, insured shooting club. Same with ammunition. No accessories at all for sale, anywhere, and felonies with real hard time for any violation.
      “What about the other guns already out there, clearly we can’t do any of the above because of them?”
      Well, here’s where the “fuck it” part comes in.
      Full confiscation or utter destruction of whatever hidey-hole of your precious weapons you are willing to die protecting.
      “We can’t take their guns because they’ll shoot back.”
      Society has a LOT more weapons than you do, and the people are getting very angry about your precious toys and obscene danger they pose to the rest of us.
      “If we did that the people with guns would shoot back and people will die.”
      I guarantee you, even if every single gun enthusiast opts to fight back with maximum violence, full confiscation of all weapons will still cost FEWER LIVES than what we have now. I am not kidding.
      This situation is disgusting. So disgusting I sometimes wonder, am I some sort of time traveling tourist? “Live like the Americans! Know what it was like to be in the richest country in the world when everything went completely off the rails.” You fucking assholes.
      You can’t shoot people without a gun in your hand. Your toy came from somewhere.
      Grow up. Join the rest of society. Get another hobby.
      You’re killing us.
      Originally posted on Twitter. See the video showing how this post was made.
      Sponsored by Kill Joy® brand guns: Be like Kyle. Someone might need killing. Best for murdering.
      You might also like the NFTs and video games rant.
    Remembering JavaScript
      (9 min read)
      I got to take the wheel for a short ride yesterday, which was spectacular, like going to the mailbox, but even better. I went to the office to unstick my keyboard, and pick up a few books, including JavaScript Patterns, an O'Reilly book with a European partridge on the cover, by Stoyan Stefanov. This book defines pretty much the extent of my knowledge of JavaScript that I don't get from random googling into Mozilla's docs. It clearly lays out pretty much every single way you can do stuff in JavaScript, and spells out some of the advantages and drawbacks of each approach.
      I found this book to be invaluable the last time I spent a lot of time with JavaScript, which was back in 2010. At the time I was putting together a virtual tabletop application that would run in the web browser.
      A virtual tabletop is a shared space for playing tabletop roleplaying games. These games are all different, by nature, but typically a tabletop roleplaying game is one where several people sit around a table, with a map, on which there are pawns, or tokens, representing the characters they are playing, or fighting, or negotiating with, or looting. Lots of dice rolling, hundreds of pages of rules determining outcomes, lots and lots of ways to customize your characters. Typically, one person will prepare an adventure, and run the game for the other players. This may span dozens of hours over several sessions of play. To make this easier, you can buy printed adventures, maps, tokens, prepainted miniatures, miniatures you can put together and paint yourself, etc.
      The virtual tabletop I built was intended to simulate all that stuff, in your browser, ten years ago, in Safari, on your desktop, on an iPhone 4, on an original old-school iPad. It had print-resolution tokens and maps that you could drag around and zoom into like Google maps, until you could literally see the individual fruit in the cart in the village square. Group and private tabbed in-character chat, like Slack, except with a non-stupid UI. Dice rolling, dice macros, combat initiative tracking. The ability to sign in simultaneously on multiple devices so you could run initiative on your phone, use your iPad for chat, and your desktop for the map. I had the opportunity to get up on stage and demonstrate this to hundreds of fans at a convention, and promise early access to all attendees. Testers were thrilled. For strategic reasons, just before final public release, that project got canceled for something else, which later got canceled for something else, which happens.
      Anyway, to make something like that, you really don't want to be subclassing everything, it's a nightmare. Let's say you have a Token, which has Token.x and Token.y. Then you have a monster, well, OK it's a Token too. Then you have a spell, which takes up a bunch of squares on the map, in a weird cross-type shape. Is it a Token? Sure, it's a thing you can place on the map at a particular location, and the shapes of Tokens can be determined by their size or cross-section or something.
      Now you want to place a thing for the person running the game to click on. The other players can't see this control, because it's for a prepared adventure, and displays some hidden text about the room and its contents. Is that a Token? Well, maybe it's a Button, which also has a Button.x and Button.y. Tokens and Buttons are totally different. Tokens can be moved around. The x,y of each Token is going to be persisted separately, for each virtual tabletop. The Button, on the other hand, has an x,y but it only needs to be persisted at the Adventure level, which means, we only need to store it in one place, because every virtual tabletop will see it at the same place.
      So it's very unlikely that you will come up with a common superclass for Token and Button, in this type of problem space. Particularly because to add new features to the application, you need to consider the front-end user interface, client-side application logic, client-server synchronization protocols and message formats, client-to-server-to-clients synchronization, server-side request-response handling, server-side application logic, data consistency, caching, and back-end data stores. The approach I chose was an entity-based system, taken from MMO video game design. Functionality was added by compositing attributes and abilities.
      In this approach to the example above, there's not really such a thing as a Token. You'd create a Thing, and you'd give it a Position, which means it would have an x,y. For a player character, you'd also give that Thing a reference to a Player. A button, on the other hand, would be a Thing with a Position, which also has a reference to a Narration.
      This object, each Thing, is dynamically constructed on the fly, based on definitions from the server. We never create a superclass. You can have ten different Things, each with different sets of attributes and capabilities, and each absolutely interchangeable from the system's perspective. As long as a Thing has a Position, and is Selectable, it can be either a token, or a button.
      Literally everything is a Thing. There are no subclasses. Each Thing, of course, has its own unique collection of capabilities (functions). The application control logic, of course, needs to have a meta-type understanding of capabilities, but it's easier this way rather than a bunch of if-then or case statements. We did use a lot of state machines, I guess, but state machines should be considered fundamental, like arrays, or hash maps.
      This is the sort of thing that's easy, or at least doable, in lots of languages. LISP is the classic, you can composite together anything you want, though I've never done enough LISP programming to know if that's actually how they solve their problems in the vernacular over there. I could make a pretty decent composition system in FORTH, too. No, I have no idea why I keep reaching toward FORTH and LISP as my go-to comparisons for JavaScript, why is that? Curious. (It would be a lot of fun to think about building the whole thing in Rust, actually.)
      In the real world you're going to use JavaScript, client- and server-side. It's suited just fine to this sort of problem, actually. But JavaScript gives you a lot of choices about how to do things, and you're going to get pretty deep into the weeds of every single possible approach to figure out the best way to stitch together these little composite entities dynamically at runtime, and still maintain your sanity, debugging and QA.
      Anyway, here are some gems, retyped or paraphrased from the book. I guess these are some of the things that, with Drumkit, I am working on ignoring. I am eliding the hell out of these quotes, but I don't think I've changed their meaning. Stupid typos are naturally mine—
        Any variable you don't declare becomes a property of the global object. [...] Regardless if created inside functions, […] properties can be deleted with the delete operator, whereas variables cannot.
        If you need to access the global object without hard-coding the identifier window, you can do the following from any level of nested function scope: var global = ( function () { return this; } } () ); This is no longer the case in strict mode. [...] You can wrap your library code in an immediate function, and then from the global scope, pass a reference to this as a parameter to your immediate function.
        [Paraphrased] You can't iterate over the properties of an object, because some of those properties might come from some other object. So you need to check that object's hasOwnProperty method to see if it's a real property and not, say, some random function named clone(). But, well, that hasOwnProperty method could have been redefined. So what you end up looks like this: for (var i in man) { if (Object.prototype.hasOwnProperty.call(man, i)) { … } }
        [Paraphrased] You can augment the prototype property for built-in constructors such as Object(), Array(), or Function(). That's right, you can add new functionality, entire functions of functionality, to functions defined with Function. This leads to super-awesome code. (OK, the book is good, and so actually says, "it can seriously hurt maintainability", and then details why.)
        JavaScript implicitly typecasts variables when you compare them. That's why comparisons such as false == 0 or "" == 0 return true.
        [Oh right, I forgot about eval(). Remembering that eval() exists is like losing the Game.]
        This code logs undefined: (function () { var local = 1; Function("console.log(typeof local);")(); }());
        The Object() constructor accepts a parameter, and […] may delegate the object creation to another built-in constructor and return a different object than you expect. [ie, you can do new Object(1) as well as new Object("1"), and also do not do this thing.]
        Self-invoking Constructor. To have prototype properties available to the instance objects, consider the following approach: In the constructor you check whether this is an instance of your constructor, and if not, the constructor invokes itself again, this time properly with new.
        ECMAScript 5 defines a new method Array.isArray(), which returns true if the argument is an array. […] If this new method is not available in your environment, you can do something like this: if (typeof Array.isArray === "undefined") { Array.isArray = function (arg) { return Object.prototype.toString.call(arg) === "[object Array]"; }; }
        To illustrate the difference between a primitive number and a number object: typeof 100 is "number", while typeof new Number(100) is "object". […] When used without new, wrapper constructors convert the argument passed to them to a primitive value: typeof Number("1") is "number", as is typeof Number(new Number()), and typeof String(1) is "string"
        Yet another syntax that accomplishes the same results is…
        In the next example, the value returned by the immediate function is a function, which will be assigned to the variable getResult and will simply return the value of res, a value that was precomputed and stored in the immediate function's closure…
        In other words, both of these work: ({ … }).init(); ({ … }.init());
      I've been skipping stuff, and we haven't even gotten to function memoization, partial application and currying; general purpose namespace functions, like var MYAPP = MYAPP || {}; implementing private members via closures; avoiding recreating private members each time the constructor is invoked; globals; sandboxes; modules; public and private static members; so much discussion of __proto__; prototype chains; simulating classes; prototypal inheritance; mix-ins; borrowing methods; binding prototypes. And a bunch of other stuff, it's a good book.
      I know some of these examples aren't fair, we're probably up to ECMAScript 12 or something by now, time marches on, and JavaScript rules everything around me. And I know Drumkit is still JavaScript underneath, really. You can probably use any old kind of JavaScript insanity you like, I am pretty sure about that.
      But for me, in addition to the pre processor, Drumkit is a voluntarily chosen subset of JavaScript. I am taking that to an extreme, I am omitting semicolons like no tomorrow. I am trying to find my Drumkit vernacular right now. All sorts of options for every decision, which I am busily paring down to the set I prefer.
      I have absolutely used many of the bananas features available to me in JavaScript before. And I may do some low-level JavaScript shenanigans at some point, somewhere. But that will be for a specific, narrow, purpose: to make the rest of my Drumkit as plain and obvious as I can make it.
      See also this previous post on JavaScript.
November 2021
  November 28
    Here's one minute with Drumkit
      This is the transcript for the DocServer Lookup v7 demo video:
      With Drummer, the entire web is your data. You can transform it to your needs.
      We do this by writing little bits of Drumkit. Here's something I made to help me look things up in DocServer.
      Let's take a look at the code and see what it does. Drummer lets me focus on just the parts I need.
      We get the selected text, we clean it, we extract a Drumkit verb, and insert the docs as a comment.
      Here's how it works: Drummer fetches the docs from over the internet, and puts them right where I need them. You can copy–paste the examples. Or collapse, or delete, the whole thing.
      Down here is where I keep my functions. I use things like bold, italics, and indentation, to make them easier for me to see and work with. Here's the one that gets the selected text. Not much code there at all.
      In Drummer, the outline is not just your code. Or your document. It's also your user interface.
      You don't have to use Drummer like this. You can use it however you want.
      I'm building something.
    Here is one minute of video showing what it is like for me to use Drummer on the iPad
    Look I made a thing
      I'm quite pleased with myself. I added a question mark to Drummer's icon bar.
      I use it to look up documentation about how Drumkit verbs work.
      It uses the same opml file as DocServer, but I find this to be more convenient.
      The docs get inserted as a comment below the current node. You can collapse it, delete it, or move it somewhere else. You can copy��paste the syntax or examples. Some Drumkit verbs, such as opml.parse, contain extensive example data in their documentation. Sections like this are automatically collapsed.
      This is a snapshot of work in progress, of course. So many things need improving. But I am having a blast.
      Update: I posted a video of how it works to Twitter.
  November 27
    How I Drummer
      Here are a couple things I wrote on Twitter about how I am approaching Drummer as a developer.
      How to Drummer
        The entire web is your data.
        You can transform it to your needs.
        You can do that whenever you like, scheduled, or click an icon.
        You can save it anywhere, it doesn’t have to be your blog.
        The environment is malleable.
        You can transform it to your needs.
      How to Drumkit
        The outline is your code.
        The outline is your scratchpad.
        The outline is your document.
        The outline is your test case.
        The outline is your console.
        The outline is your documentation.
        The outline is your user interface.
  November 26
    Flying
      (10 min read)
      This weekend is for writing essays and Drumkit. Mostly what I need at the moment are some IDE-type tools. Documentation lookup, that sort of thing. Some of these are things that Drummer probably ought to have built-in, and may, someday. Since Drummer is scriptable, though, I can make someday happen today.
      For example, yesterday's project, which is basically "go to line number". Here's part of the inline documentation:
        // To use this
          Drummer displays a dialog box like this when it encounters an error in your script:
          Error running script: Unexpected token (25:5).
            The first number is the line number, which Drummer gets by counting all nodes that aren't commented-out from the top of the script.
            The second number is the character position within the line.
          You can copy the entire text of the dialog box, or just make a note of the line number.
          Click the icon. You can paste the text, or just type the line number.
          Drummer will either go to the indicated node, or beep if we can't find it.
      I'm on schedule with my Drumkit code this weekend. I knew I wouldn't get anything actually built yesterday, because I am still working through the implications of how I am putting together my code. I think I've concluded that part, and can now start actually building some things I need.
      As I noted yesterday, I really like working in Drummer. There are some things I spend time working around, but overall, I like the experience. Working in an outliner is amazing. Being able to pin a function, or a group of functions, is ridiculously useful.
      Yesterday's post didn't even list all the ways I've found to screw things up in Drummer. I've managed to make tabs that can't be closed. Documents that suddenly become literally entire other documents, as if a wormhole had opened. These are hard to file issues for. I spent several days last week trying to get repro steps to demonstrate the wormhole bug, and the one I suspect makes the bookmarks menu a vortex of destruction. I can't do it reliably, so I can't file, which is a shame.
      I admit I have given up trying to get repro steps for those. I am reluctant to experiment any further, even though I now know how to restore things—I think—if everything goes sideways. (That tab is still there, taunting me. We have an agreement now, that tab and I.)
      But why would I spend any time at all working in an environment where catastrophic failure could occur at any moment? This is so not like me, I do not like unsafe things. If I find a safe way to do something, I do it that way.
      I once test drove a Honda S2000, which is a tiny car with an engine that is happiest at extremely high revs. If you take that car on the freeway, possibly already above the speed limit, and it is spinning at, say, 7,000 RPM, which is red line for most cars, and then punch it, that car jumps up to 10,000 RPM. This feels like it just grew another engine, and the car asks, "Did you feel that? Being slammed into your seat like that? That is what we call a G force." This can be extremely exciting, which is why we buy cars like that, and jump out of airplanes. But, to me, it did not feel safe (I would be too tempted), so I kept looking. The failure mode there is death and destruction.
      My brother used to ride a motorcycle, and wrecked it, and had the usual doctor-type stuff to put himself back together. That feels pretty unsafe to me, so I have never actually operated a motorcycle myself. The failure mode there is pretty bad.
      However, I now spend lots of time, like, every minute I can, operating a device which is basically the most dangerous thing I own. It may also be the best thing I own. It's an electric unicycle. I call it "the wheel". And its failure mode can be summarized as fuck you.
      The wheel is a result of Segway-type self-balancing technology. You stand on it, it stays up, you lean, it goes.
      You know the problem with a Segway? Too many wheels and handles. You know that thing the caveman rode around on in the B.C. comics? That's what the wheel looks like. It is literally a wheel with some pedals sticking out.
      The wheel is like flying. Riding the wheel feels exactly like you are standing on a magic carpet, a few inches off the ground, and you are flying wherever you want to go. You don't operate any controls. I ride with my hands in my pockets, sometimes. You just think a direction, and you are moving there. I am not kidding.
      When it is time to fetch the mail, I get to ride the wheel for maybe a total of 30 or 40 seconds. The wheel weighs sixty pounds, and I have to carry it up and down a flight of stairs. I look forward to getting the mail. I come back smiling, every single time.
      The wheel stays up, by itself, self-balancing, but only front-to-back. That's how you make it go, you lean forward, it tries to stay upright, so it accelerates to get back under you. You have to maintain your side-to-side balance, though. If you have ever done any sort of balance sport like skiing, or skateboarding, you will take to it immediately. I did not. It took me weeks to learn to stay up on it. This was literally the hardest thing I have ever had to learn.
      I could probably do a skateboard now. But I don't want to. The wheel is so much better. I can ride it off-road. I don't even need pavement.
      (Do not confuse the wheel with a OneWheel. That thing is a powered snowboard, you ride it different, it is different.)
      The wheel requires power to stay up. When you turn it off, it immediately slumps over, limp. It is like turning off a live thing.
      There is a button that you have to hold, if you pick it up off the ground. If you do not hold that button, while lifting it, the wheel thinks it needs to accelerate to catch up. So within a couple seconds, that wheel will be spinning literally as fast as the motor will go. It is hard to hold on to, because it produces torque like a gyroscope, this is how fast it is spinning. This is part of the specifications for a wheel, what is the maximum power it can apply when it doesn't have to do any work.
      If you forget to hold the button, and then set the wheel on the ground while it is doing this, your wheel will attempt to go somewhere else. It will leave skid marks, and if you do not have an absolutely firm grip, your wheel will achieve an extremely high speed, very quickly. This won't last long, because a tenth of a second later, something will be smashed. Since you're right there, it'll probably be some part of you. You want to hold on, because if you let go, the wheel will go berserk, and you need to find that stupid button. But you can't, because the wheel is going berserk in mid-air, and putting skid marks on you in the process. Usually it's best to just let go, and watch it crash into things until it decides to stop on its own in a few seconds.
      When you lean forward, the wheel accelerates to keep under you. If it cannot keep up, that means you are going faster than the wheel. You will continue going faster than the wheel, for a short time. You will continue going forward, for a short time. You are leaning forward. You will keep leaning forward, for a short time, until you complete a maneuver which is technically referred to as a "face plant".
      The wheel might not be able to keep up because you are asking it to go too fast. It might not be able to keep up because the battery is low.
      If you demand too much current from the battery, it will go as fast as it can, but you can always lean past that point. There is no way to make this safe. Either the wheel literally has the power to keep up, or it cannot.
      You can fake a safety mechanism by pretending to retain some reserve. The wheel will beep at you, loud as it can, if it detects things like going over a certain speed, or temporary current draws more than 90 amps, or the battery voltage is getting low. But it can't do anything else, it cannot slow you down: The wheel cannot slow you down. If it tries to slow you down, you face plant, because you are then going faster than the wheel.
      If you are going fast—mine will go 20 miles per hour, newer ones are approaching freeway speeds—you may not hear the beep. So there's another thing called tilt back, which I call pushback, due to the way it feels. This basically means the wheel adjusts its acceleration curves such that it feels like you have to lean harder, and harder, and harder, to go any faster. This is uncomfortable, and you have to deliberately ride through pushback if you want to keep going. You can, though. Right up to the point where you draw too much current, and the wheel can no longer keep up. Which means, face plant, at high velocity.
      The wheel will recharge its batteries if you go downhill, which is great. But if the battery can't take any more charge, well, I think you might guess where this is going. So you never start a ride at 100 percent battery, if your ride is going to start at the top of a hill.
      Like I said, the failure mode on the wheel can be summarized as fuck you.
      But it's not that bad. It's exciting. You have to be extremely aware, at all times, of what's going on. You are moving fast, among pedestrians, and cars, and they are absolutely not used to seeing someone riding a wheel. This cognitive dissonance can cause poor decision-making in situations where you do not want that—I do not want to confuse drivers who think I'm a pedestrian and don't realize how fast I can move, so I generally walk the wheel through intersections.
      You have to maintain your balance, on a platform that is jumping and shuddering with cracks in the sidewalk, or bumpy ground. You get used to the idea that your feet might need to leave the pedals, briefly, but you'll be OK. Someday I will try one of the newer wheels that have a suspension, that sounds pretty nice.
      To ride the wheel is to fly, and be alert. The failure mode is a face plant, but I have safety equipment, and don't ride at the limits of the wheel. So, it's thrilling, but mostly safe. Mostly. For example, after several weeks initial practice, I decided I was ready to go get some coffee, and of course, fell off the wheel on the way back. (Saved the coffee.) That knee hurt for weeks.
      I can't remember the last time that happened, though. I learn, I practice, I get better. I use the wheel to get groceries. It has a handle, so I can just walk it around the aisles like a pet. When my car is in the shop, I ride the wheel a few miles to the rental place. I rode the wheel to get vaccinated a couple times, and I'll do it again to get my booster. If I have to go anywhere, and I can carry what I need in a backpack, and the weather isn't terrible, I take the wheel.
      In short, the wheel is fucking awesome.
      Working with Drummer feels like riding the wheel. It is exciting, and unlike anything else. It's also dangerous, you need to stay alert.
      But the failure mode isn't all that bad, really. It doesn't even hurt! Not like a knee.
      Like I said yesterday, I am getting used to writing things twice, occasionally. I am not kidding about that, it has been an invaluable lesson about the real uniqueness and worth of any individual, specific, thing I create.
      I used to think, I need to make this perfect, I have to get it right. And I never, ever produced anything.
      Knowing that I wrote it before, I can do it again, and maybe I'll find a better way to do it, has been good for me. No joke.
  November 25
    The Sunday post
      I've been having enormous fun with Drummer today, but it's time to set the Drumkit aside for now. That doesn't mean I'm setting Drummer aside. I am switching context, which is super easy in this blogging environment, which is also a customizable publishing tool, which is also a generalized internet thingie development environment, which may yet turn out to be a toaster that can cause lizards to suddenly fall from the sky.
      It's probably other things to other people—in fact, I know it must be other things to other people, that is how this works���but those are some of the areas I'm using Drummer for. Some of my internet thingie development stuff is probably really, incredibly stupid. (I may need to re-think that whole lizard thing.)
      Which brings me to what I'm switching over to, which is the next Sunday post, which is going to be about stupidy again.
      There is a thing in the universe called "stupidy". Like entropy, stupidy increases. Stupidy is a concept and property which assists in calculating, and reasoning about, the amount of "wtf" in an environment. This increases with the number of participants in, and connections between—and isolation from—various social groups.
      Why are entire swaths of society able to hold beliefs which are, inarguably, deadly only to those who hold these beliefs? Stupidy has increased.
      I've done a lot of things in my career. See my bio for some of the highlights. Some of the things I've done have provided me unique insights into stupidy. How it works, how it grows, and how it can lead to some completely amazing, surprising, wonderful, things.
      I am not talking about Facebook scale, of course. But stupidy is the study of these relationships at literally every scale.
    Notes on working with Drumkit
      I'm going to be writing a lot of Drumkit over the next few days, and I'm really, really looking forward to it. This is turning out to be more fun, and in some ways, better, than working in an IDE. I did not expect that, not one bit. I was expecting working inside Drummer to be a set of painful compromises. Here are some notes I'm typing up about the experience as I go.
      The good, which is really, really good
      I really like starting with a previously built thing, like an icon or a menu item. It gives me a prebuilt idea about how I might approach the problem, and I can easily grab entire labeled groups of functions from an icon, and drop them into a menu item as a scaffold for something else.
      Writing the instructions for how to use it before even going near the code section is the way it should be. It forces me to think through each step of what I am claiming this code does, and how I intend to do it.
      Inline user and dev documentation is the way to go. Separating the concepts of label, description, explanation and disabled code is clarifying and instantly makes it easier to navigate.
      Trying chunks of code and just command-backslash to toggle them in and out is amazing. These do not have to be individual lines, you can do entire grouped hierarchies of functions. Or just a chunk of a function. What is that, a paragraph? I guess it's a block. (Given names like Drummer and Drumkit, it's probably a wooden block you hit with a stick. Maybe a cajon...)
      I miss autocomplete and hover to bring up contextual documentation. Fortunately that is the next thing I am going to build after the little snippet I'm writing now.
      I do not know what to call these chunks of Drumkit. So far I have referred to them with terms like snippets, thingies and chunks. A coworker suggested drums. I realized that I could just omit the word if I phrase it correctly, so for now I am going with "This Drumkit does blah blah".
      Maybe "script" is the right word. This Drumkit script does blah blah. Here is where I keep the Drumkit scripts. Enh. I am not feeling that.
      My use of ad hoc function categories, and the choice to emphasize plain English headers, rather than method names, using formatting like bold text, makes it SO MUCH EASIER to navigate my code, I cannot overstate this.
      Not running everything through a standard, language- or project-specified, source code formatter is making me happy. Enforcing standard formatting helps me not go insane when other developers make The Wrong Formatting Decisions. But this is my fucking code. I can format it however the hell I want. My decisions about runs of white space are based on context and choice, not pattern matching.
      I may have mentioned, I care a lot about how my code reads, and Drumkit is letting me also not care about anybody else's opinions on that. No one else writes their Drumkit code like this, I can't imagine anybody else would feel comfortable working like this. It requires a lot of extra formatting. You have to go back and rework running code. You write far more comments than you'd think are really necessary.
      All the other Drumkit code I've seen looks like regular source code, all semicolons and braces and function names and variables. This is how we write code, this is what it looks like normally. You stop when it works. I keep going, because I want it to read well, too.
      If you write some code, and decide to make it a function, you are working in an outliner. So all you do is, insert a node above the lines you are going to extract into a function, put the "function blah() {" etc stuff there, then just tab the nodes to indent them under the function, add a close brace, and now you can just drag that sucker wherever you like.
      The bad, which is really, really, really fucking bad
      If you have a node selected and you accidentally hit backspace twice, you are fucked. You cannot possibly undo this. You can undo one of the backspaces, and get one of the nodes back. The other backspace has consumed the other node, and everything under it, even a nice group of functions you've worked on for hours. It is gone. You cannot get it back. Gone. I've also lost major chunks of blog posts this way.
      If you don't notice you've done this, if you just hit undo to get the node back, and keep going, entire if-then blocks or paragraphs can disappear. Why isn't it working now? I thought I had that fixed. Oh right, that whole error-checking part is apparently gone now. What did that do again?
      This also comes up in a different context. If you hit command-return, and split a node at the wrong place, my first instinct is to hit undo. Splitting the node is apparently two operations, however. If you hit undo, what gets undone is the insertion of the text into the new node. So you end up with half your text in the first node, and a new, empty, node. Half your text is gone. If you do not immediately hit undo again, you will not get it back. You are fucked.
      And if you do remember to hit undo precisely twice—not once, not three times, but only twice shall you hit undo—your text is now in two nodes anyway, and you cannot undo that. I have been reminded that the keystroke to backspace a node into another node is, in fact, command-backspace. However, this does not always work. And, you have to navigate the cursor to the right spot. Because when you split the node, the text insertion point is now at the end of the newly inserted text in the newly inserted node.
      So you need to click on the exact spot where the text begins, which means, you are very likely to accidentally select the entire node, instead of placing the cursor where command-backspace will do any good. I'd try it right now to see what command-backspace does when you've got an entire node selected, but I don't want to. My brain needs patterns that are safe. When I find a way to do something that is safe, I do it that way. Command-backspace does not feel safe.
      I cannot overstate how careful I try to be with the backspace key. If I want to delete a node, I pause, and look, and double-check what I am seeing, and then after hitting backspace, pull my hand away from the keyboard like it was electrified. Keybounce may not be a problem, but my hands get jittery when I'm excited, and I cannot help it, I get jittery when I might be about to lose a bunch of work if I fuck it up.
      Anyway, my first, first, first instinct is always, always, always, to use undo. That this is not the right thing to do in Drummer, and, in fact is an instant ride to lost-your-data town, unless you start thinking very, very carefully about what you are doing, is a shame. See this previous post.
      I'd like it if Drummer had multiple undo. But that is probably an enormous rewrite of Concord, which is based on literally decades of experience and outliner code that works the way it does for very good reasons. It's a completely unreasonable ask, and not something worth filing as an issue. Just having repro steps for something isn't enough.
      (It's also entirely possible, even probable, that some or all of these are only problems because I'm using an iPad, which, I'm probably the only one in the world. I am certainly not going to file an issue for something that literally affects only me, that's nuts. The drummerSupport repository functions as a todo list for Dave, it is not there for user support.)
      I am learning to embrace the fact that if I wrote it once, I can write it again. I generally do it better the second time, anyway. Probably.
      Back to the fucking awesome part
      The fact that I am still willing to put this much time and effort into Drummer����even though a stray keystroke, or trackpad tap, could, and has, repeatedly, obliterated non-trivial amounts of work—should be clear evidence of just how fucking awesome Drummer is.
      I just realized today is Thanksgiving, so, umm, Dave, I accidentally kind of got loud at the blog version of the dinner table here, and I am sorry about that. But, really, thank you. Drummer is fucking awesome, and I will keep using it like crazy, even if it never gets multiple undo. No joke.
      I don't say thank you enough. Thank you, Dave. You have made something amazing here, and you should be proud.
      OK, back to the fun part. I got some more Drumkit to write, yes, I do....
  November 24
    That's the way I like it
      I am having a lot of fun with Drumkit. I care a lot about how my code looks, and it has been great being able to use bold, italics, etc, and separate indentation and collapsibility from language structure. I’m sure my Drumkit doesn���t look like anyone else’s, but I like it
      The method capitalization is due to autocorrect on the iPad, I decided to run with it and see how it feels. At first I thought this is a ridiculous amount of commenting and formatting for a few lines of code, but I found I missed it when working on some code I hadnt done that way
      You can basically stick that outline as-is into your menu.opml outline. It’s just commented code, but it feels different to me. Every part of that is just convention, by the weekend my code will look and read totally different.Drumkit is fun, in a way I haven’t had since Basic
      I wrote most of this post on Twitter. I used Drummer's Get my tweets... command. This created an outline, with each node a tweet. I found the one with the screenshot, and added it to this blog post. Then I used Drummer's pin icon so all I saw was the list of my tweets. I then used the Open in iA Writer as New File command that I wrote myself, which copied all the text from the tweets over to iA Writer for some quick cleanup. I then selected all that, pasted it into this blog post, and wrote this paragraph.
      This took less time than the pot on the stove to come to boil. I am not kidding. Have I mentioned that Drummer is fucking awesome?
      Yes, I am posting screenshots of my Drumkit code. Yes, I am a huge fucking nerd. Yes, this is how I plan to spend my holiday weekend. Yes, I am a huge fucking nerd. I said this time, I am leaning in, good day sir!
  November 23
    Please let there still be a blog part
      My blog file got replaced with the contents of my icon bar.
      I am trying to restore from a backup. I don't know how to do this. Please let this work.
      I deleted the nodes in this icon bar, and imported the local file.
      Looks like OPML headers are gone so my blog is now titled ICONBAR.
      Maybe I should keep that.
      This is too distressing. I don't know how I did it and I can't file a bug. There's been a tab I can't close for days. Maybe it ate my blog. Maybe I did it. I probably did it. I have fucked up so many things.
      I am going to try to fix ICONBAR, and then maybe take a break from Drummer and Twitter and blogging and everything else. It's not good to be this wrapped up in something.
      And it's a good opportunity to remind myself that really, it doesn't matter if I'm doing this stuff or not.
  November 18
    Typographical escapes
      (11 min read)
      Yesterday's post reminded me of another case where I might want returns inside a node in a Drummer outline: Twitter rants. Drummer has a sweet feature for posting threads, you just put the individual posts in an outline, and then Drummer can post the entire thing.
      I cannot tell you how hard it is for me to use Twitter's threading feature. I am not an idiot, and have been working with virtualities and user interfaces for a very long time. But there is something about posting a rant on Twitter which defeats me. I should just plan them ahead of time, and then post them using Drummer.
      What I actually do is, I post something. Then I think, I should post about that again, so I will reply. Then, it is time to post again. Within moments, things inevitably go strange. I do not know how it is possible but Twitter lets me create some sort of horrific Klein bottle of an ortolan of a thread, where I believe it may be literally impossible to read every post in, say, chronological order.
      What I have discovered is, I can reply to exactly one post, creating a thread of exactly two posts in length. This is reliable, and works great. So I have decided any long-form Twitter ranting has to be done in advance.
      This is not how I have used Twitter for the past decade or so. Until quite recently, I have used it for one thing: an app where I can hit the "new post" button and instantly have a little problem to solve. The key is instantly, these things have to be done as fast as possible. If it looks like I put no time into it, that's because I am using Twitter to force me to get an idea out there somehow, instead of just keeping them all in my head.
      I have had a lot of fun within the restrictions that Twitter imposes. For years, I never used pictures, just the text part, and I would go off and do things like post dozens of political jokes in a very short time. Being forced to watch every single character, especially at the old limit, while trying to present an entire multi-panel cartoon, and simply implying the drawings, is amazing amounts of fun. I keep telling myself I should hire an artist to illustrate them, but I will probably just turn them into a book as is.
      Ten years of doing this has gotten me pretty good at tricks to save space. I used to have to fit stories for column inches back in the old-timey newspaper design portion of my career, so I know lots of things typesetters have been doing for centuries to manipulate how much space something takes.
      You adjust the spacing between letters, between words, you use hyphenation, you condense or expand the shapes of the letters themselves, you hand-kern to get one more point to pull that word up and avoid the river, you can adjust the font size itself up or down, you can make the initial indents for paragraphs larger or smaller, you can manipulate the space surrounding em dashes and en dashes, you can make your inset caps larger or smaller, you can increase or decrease the leading, which is the space between the lines, you can manipulate the spacing between paragraphs, you can add or remove or edit pull quotes, you can adjust the space between, or presence of, design elements which call out the pull quotes, you can spread it across two columns, or three, you can even go off the grid and shave a few points off your column width but retain the overall spacing so the advertising columns stay the right size.
      If all that fails, you can go back to the editor responsible for the story, and see if maybe we can work something out. Usually they're not complete fucking assholes, and will agree that yes, we could possibly cut an entire word from the story to keep it to three pages.
      Sometimes, not. I once worked with an asshole who refused, because the story was literally perfect. This is not actually possible, and I get the whole "I am making a point about how you should never, ever, ask me to do something as fucking basic as make your job one tiny fucking bit easier, ever again" thing, but, come on.
      This is the same genius who once called me into his office to complain that his computer wouldn't turn on. Because I was an asshole myself at that time, I asked him, "Is it plugged in?" Because that's a dick thing to ask.
      Obviously, it was not plugged in.
      His office mate, who was not in fact a complete fucking asshole, as I recall, had unplugged something and plugged in a fan. Apologies were had. Ha! No fucking way.
      After lunch, I was again called in there by Mr. My Prose Literally Cannot Be Edited for Brevity. Apparently his computer was not working, again. He was not amused, I guess because had perfect words to type up or something, and this was going to fuck with his deadline or some shit. It's always something with some people.
      Obviously, I again asked him if it was plugged in.
      Obviously, it was, in fact, unplugged again.
      You can guess just how profuse the apologies were not, and the gratitude that was not expressed. I am not actually sure if I'd ever seen a face that color, it was a really cool purple effect. I forget if he was one of those guys that's angry all the time, or if his face was just like that. I am pretty sure he wasn't like that sales rep that always smelled of vodka because apparently people can't smell that shit? We are really good at constructing stories about reality that help us avoid dealing with our actual effect on the world.
      I like to think now, had I been that guy, in that situation, I would have not stopped laughing for several minutes, and people probably would wonder about the giggles for the rest of the day.
      Anyway, you can't use most of those typographical tricks on Twitter. What I usually do is type it up with proper spelling, punctuation, everything, including "p.m." instead of "pm". This gives me stuff I can go back and cut without changing the meaning.
      When you're constructing a multi-panel joke, you use white space instead of illustrations or a grid to break up, present, and punctuate the story. You can't just jam it all into a single paragraph, not usually, you need air to let the joke breathe and hit its beats. So an individual post will consist of multiple lines, separated by returns.
      Which brings us back to Drummer and its nifty rant feature. The problem is, each node is treated as a separate tweet. Since, in Drummer, a return is a node, that means each tweet is one node. Which means, I can't actually use Drummer to post a multipart rant if I want to use the extremely limited set of tools I have available—basically, text and vertical white space—to maximize what I can get out of a single tweet.
      There are a few ways to get around this. Instead of a tweet corresponding to a single node, I could have a tweet correspond to a sub-array of nodes, which get stitched together. Basically, a multi-level outline, where the top level nodes are the tweets. This is probably the way to go.
      Because one of my goals for the blog part is to post ideas that I haven't gotten around to doing yet, and thinking about things like this is my happy place, and things elsewhere are as crazy as you'd expect with stupidy on the rise like that, here's one I've been thinking about.
      (As with most of my ideas, I like it and I also think it's probably stupid. Which is more fun than thinking I am an idiot and should just shut the fuck up. Where's the fun in that, abusive voice in my head? You know, if anybody else talked to me the way I talk to myself, I'd tell that asshole to fuck right off. Nobody has time for that shit.)
      The other way we generally solve the problem of "how do I put something into some place where it doesn't fit" is, we map that something somewhere else, temporarily. We transform the symbols somehow, so we don't treat them the way we usually would. In this case, we'd want Drummer to occasionally treat a return as something other than a node.
      And to do that, we can slip through an escape hatch into a separate, bubble universe. Inside there, we can do whatever we want, and it won't affect the outside world.
      The escape hatch is an escape character, and it's usually a backslash. To indicate the next character is to be treated as something other than normal, you put a backslash in front of it. This works great. If you use quotation marks to delimit the beginning and end of a string, and you need to put a quotation mark within the string, you just put a backslash in front of that quotation mark. This ends up looking something like "\"This is\", they say, \"really easy \(if \"easy\" is the right word\"\), to read." (You'll note, that sentence isn't even properly punctuated in the first place. It is really, really hard to see this type of thing.)
      Of course, the instant you start using the backslash to denote "this is weird", you will need to include a sentence that uses a backslash, and then you are deep into the \"weeds\", as they say. Because you start getting fun things like, well, that backslash is special, so it can end up looking more like \"\\\\ oh fuck, I have no fucking idea how many backslashes I need to include here to get just one properly escaped backslash\", and because the backslash you want to encode is actually intended for a regular expression embedded inside some other representation inside some other encoding, you need to include two backslashes for each backslash, and one before that one, and then one before that, and then you go do something else for awhile until your brain uncurls enough to deal again.
      Eventually, you will get it right, but this sort of thing is really, really hard to maintain, because by the next day, your brain will no longer be able to see it properly, and you will have to work your way through all the escape sequences again, just to get back to where you were. If someone else wrote it, or it's been more than a week, depending on the change you need to make, it may even be faster to just start over from scratch.
      You may be able to detect that I dislike these escape things. If I were laying out computer code like a typographer, there is no fucking way I would use escape characters. We have them already, for quotation marks, and we have conventions for nesting them. These can get confusing, if you nest too deeply, but most writers won't go more than one or two levels.
      If I were going to solve this problem visually, I would use a different typeface. I probably wouldn't use color by default, that's harder to reproduce under all circumstances (what if all I have is black and white, what if all I have is one spot color, what if my reader is colorblind). I'd look at things like bold, and italic, which, if you think about, are already typographical ways of indicating that we are operating at a different level.
      I dunno for sure how this would work in practice, perhaps separate Unicode ranges, perhaps a character that says "shift to a new range". But the goal would be, the characters that I'm seeing and working with don't need to have a slash in front of them, because there is some other way of distinguishing which level I want to treat them as, both visually, and as encoded in the file itself.
      Programming languages are the way they are, basically because you need to be able to use them with punch cards. No, really. You can't get fancy with programming languages, because they have to be representable as plain old text. This notion gets updated, it used to be ASCII, now it is UTF, but the idea is the same.
      Maybe the language should be serialized as something more complicated. This is stupid, you should use BNF and lexx and whatever, I know. Even Smalltalk is representable in text. Though it was basically always distributed as a compiled virtual machine image that you could go exploring in, you could also serialize it to a text file, run it through a compiler, and get an image back.
      Python has always annoyed me with the whole "we use white space to denote block structure", but I've gotten used to the idea that editors can have enough smarts to assist with that sort of thing and make it work.
      One really interesting thing about Drumkit, is that while it looks like JavaScript, and you work with it as text characters you can edit, it is stored as an outline. The outline contains a bunch of metadata that's not required for the code to operate, like indent level.
      It's a little weird to see curly braces in there, denoting things like blocks, because part of Drumkit's heritage comes from UserTalk. That's another language, presented in an outliner, which is so defined by the nature of an outliner that it completely does away with things like those block-defining braces in the first place. Instead, it uses the node structure of the outline.
      While we're at it, I don't think I like storing my code in text files anymore, anyway. Maybe the versionable unit should be something smaller, like a function. Or even smaller, like a block. How about a constant? Or even "thing we use to hold this value which represents the velocity"? How small could that individual, versionable, unit actually be, and still be useful?
  November 17
    Discarding an idea
      This post started as an experiment to explore using iA Writer as an external editor for Markdown nodes in Drummer on the iPad. I've since concluded that my idea isn't fully baked, so I'm setting it aside.
      One of the things that attracts me to thinking about Drummer is that, even though there are eighty billion moving parts between me typing and you reading, it feels reasonably simple to me. It did not at first, see my earliest posts, where I didn't have a picture in my brain of how Drummer works. But now I think I get it, which means I can think about it before I start coding.
      In the end, this particular idea would probably be like 5 lines of Drumkit or something. If that much. Just stitching together a URL. I used to just start typing. I have a feeling I think more before I start coding than I used to. I like to have as complete a picture in my head of what I'm working on. I use the IDE and search and whatnot, I don't need to have it memorized. I can go find whatever string assembly verbs I need when I get there.
      Today, for example, I found myself thinking of a table in a SQL database as being used like a list, rather than a set. You could also think about the uniqueness constraint on the column. Inside the database engine it's probably a tree of linked lists or something else bananas. But the ability to think about it as a list, or a set, means you don't need to think about SQL, you could take the entire problem right out of SQL and move it into some other language, some other internal data structure. I like names, a lot, but really, it's the concept, the thing the name symbolizes, that matters.
      The idea I'm discarding was to hand a single node over to iA Writer, which would contain Markdown text consisting of multiple lines of headlines, paragraphs, etc. To do this, you need to solve two problems: getting the text out of Drummer and into iA Writer; and then going back the other way.
      There are two obvious ways to get the text of a node out of Drummer into iA Writer. If you fetch a URL that starts with "ia-writer://", the rest of it gets handed off to iA Writer. You could encode the text into the URL, but there's a 4K limit. The other way would be to have Drummer write a file on the iPad, most likely by simply saving a download somewhere. There may be sandbox issues with that.
      Getting the text back into Drummer looks like a pretty straightforward call from Drummer to iA Writer, again via URL, which would return the contents of the file.
      The sample Markdown file, however, shows a similar structure to a blog post in Drummer, which I should have expected. That is, a headline is a node, a paragraph is a node, etc. That's not how iA Writer views Markdown. I checked the source for Old School, and it looks like there's nothing that would prevent me from having a node that has a bunch of headlines and paragraphs. Each node is handed off separately, but the code to process the Markdown is in a library, which means, it was written to handle a stream of Markdown rather than individual Markdown nodes. (I guess there could be a library out there designed to process Markdown nodes, but I can't think why anybody would write one. Markdown is a stream.)
      I try to work through an idea before I start typing up code, and when I started working through what it would be like to actually use this iA Writer/Drummer connection, I realized that I had missed a hugely important piece of the puzzle. I can't figure out how I would work with the text on the Drummer side. I can't flip back and forth to iA Writer just to fix a typo, that's nuts.
      But Drummer does not like nodes with multiple paragraphs. I can't even picture the keystrokes or gestures I could use, the clicks or taps, that would let me properly edit my hypothetical node that contains returns and blank lines. I have a hard enough time dealing with paragraphs I've accidentally split by hitting command-return at the wrong spot.
      (On the iPad, if you do this, and then hit undo, what gets undone is the text insertion into the new node, not the split. So everything after the split is gone, unless you immediately undo again. You cannot undo the split. I think there may be a way to backspace the nodes back together, but I apparently have a blind spot in my brain for remembering what it is. My excuse is that I'm distracted, because I write long paragraphs, and then split them up in a later editing pass. If I split a paragraph at the wrong spot, I then have to navigate between two separate nodes, copy and pasting carefully to ensure I'm just moving text and not nodes. I think a lot about editing nodes and the return key, is what I am saying.)
        Update: See this post for additional context.
      "Each return is a node" feels like a pretty rock-solid virtuality, and I doubt there's some sort of wishy-washy half-baked multiline text editor mode lurking around somewhere underneath. It’s possible I've missed something about how to work with Drummer's outliner, but I feel like I would have noticed this by now.
      Splitting a stream into nodes and back again isn't really a problem I feel like dealing with. At that point, I may as well be writing a parser, because, well, I would be.
      So I'm discarding the idea for now, which is no big deal, I have more ideas than I can use.
      I still haven't built a tagging system because I don't need one just yet, and I need to get a feel for what I actually do need. So far, I'm trying basically everything, to see what I feel comfortable with, to see what I naturally want to do. Because I get so, so, so many ideas, I need to focus on doing the ones I just can't help but doing. Like I discovered with blogging, see the very first posts here.
      Part of why I have the blog part is to spin off some of those extra ideas, I can't do them all, I couldn't actually do one percent of my ideas. There is nothing worse than an idea sitting there, where I think, I should work on that because it is a good idea, but I don't want to, because I am interested in something else right now. Those ideas just sit there and corrode. The ideas don't rust, but they are bad for my soul. I need to get rid of them. Maybe someone else can do something with it.
      All those ideas I'm talking about are different, of course, from the couple hundred projects I actually have taken on. Those I totally will finish someday, I swear....
  November 14
    Stupidy, or why Mark Zuckerberg may actually be the biggest fucking asshole in history
      (25 min read)
      It's a provocative statement, given the king of England, and Donald Trump, who may yet turn out to be the actual, literal antichrist.
      But hear me out:
        There is a thing in the universe called stupidy.
        Like entropy, stupidy increases.
      ~
      When I was a kid, and I first learned about things like human sacrifices and slavery, I would try to imagine it. What would it be like to live in a place, where everybody around you thinks, "This incredibly insane idea is perfectly valid and natural."
      And people are tied up and torn apart and set on fire for saying things or, really, just being different. And people walk around thinking that literally owning a person is, like, totally fine.
      Because that shit is seriously fucked up.
      So, I would say to myself, I am really glad that I am growing up here in the present, where people are not insane.
      Later, of course, the present turned into the future, and we're all living here now. And nobody has any insane belief systems that result in the voluntary death for those that hold those beliefs. Which, if they did exist, those imaginary beliefs would have come from literally nowhere, thin air, because who could have predicted?
      And there are only approximately eleventy trillion guns, which is one giant fucking shotgun up on there on the mantle for the third act. And while we all wait for Donald Trump to order up, mob boss style, that final act of our great nation, people will literally get up and defend the "right" to terrorize, and intimidate, and especially, retain the capability at all times to murder as many people as possible. At any given moment, in any social situation, as fast as possible.
      Because you just never know when a whole lot of people might need killing. I mean, someone might ask you to wear a mask. Or treat them with basic human respect.
      And white America is dealing quite rationally with the fact that nearly everybody that is out there in the cold and rain, operating a leaf blower, everybody in the back of the restaurant, everybody working so hard and trying so desperately to just have families and children, practically every one of them has darker skin, and is paid and treated like shit. Even the ones working indoors, our doctors, our teachers, our engineers, our reporters, all the professionals white people will pretend are social equals, every one of them. All those brown people with accents, or different faces, the ones we make fun of when we get home. Guess what, they can hear that contempt just fine.
      Maybe their parents just got here, and they're just a little kid.
      Or maybe their families have been here for generations, restricted, lied to, held down, limited, swindled, bulldozed for on-ramps, crushed just one little bit more. Because what happened last generation just wasn't quite enough, we really needed to jam this shit home: you will never, ever be like the rest of us. And it scares us that you know that, so stay the fuck out of sight and for god's sake, shut the fuck up about shit. (Unless we can exploit that, because that is how we roll.)
      And these people are just as smart, and talented, and amazing as any of the rest of us, they are the rest of us, they are us, they are my people, and yours, too. We're all people.
      And there is a literal, actual, mass-slaughter atrocity war going on south of here, right this very fucking minute. It is engulfing entire nations, and it's due specifically to things America did in the past, and it's continuing due specifically to things we can change here, now, and nobody gives a fucking shit. Fuck you, slavery. You haven't ended. We can look right past you and what you made us all do to each other, what you are doing to us right now. We don't even see that shit.
      ~
      My inability to see this, how things really work, that was a failure of my education.
      I was taught that we are all in this together, working together to build something magical, something unique in history, a place where every single fucking person can do their best and NOBODY, not even the king of fucking England, can stop us when we get together.
      We may have fucked up in the past, with slavery and genocide, but there is a great arc toward justice. We will all muddle through together, and do the right thing.
      But I didn't know about stupidy then, so I couldn't see what was there around me, nor properly reason about what was coming.
      ~
      Stupidy is a concept and property which attempts to define and measure the amount of, basically, “wtf” in a social and physical environment. As connections between actors increase, the effective distance of the impact of their actions decreases. So individual actions are influenced by those further and further away (physically, socially, culturally, financially).
      And the more likely that any individual actor can have an inadvertently outsized influence. I am not talking about billionaires in that sentence. If you like, picture someone ten thousand miles away accidentally stomping a butterfly, and suddenly lizards are raining from the sky over here. That kind of wtf. We have no fucking idea what's coming.
      ~
      Why does COVID feel crazier than things used to be? Stupidy has increased.
      People self-select into communities, and in-group/out-group social pressures continually hive off new communities. This is not new, of course. But over time the number of splinter communities/belief systems will always increase. And the beliefs in those systems will always grow in intensity. (If they don’t, you go elsewhere.) Over time, criteria used to select will always get more stringent, which sharpens the division between one group and the next, and guarantees that there can never be global consensus reality.
      So a lot of the terms of the stupidy equations deal with social connections, and estimating the overall flux in belief grouping. There are also terms for things like information propagation latency and bandwidth, encoding, error/mutation rates. Stupidy theory also tries to account for toxicity—the likelihood that beliefs increase danger to outgroups, the likelihood that an advance in materials science will result in a better way to kill, or damage the environment.
      Stupidy theory isn’t just about information and belief systems, though sometimes it can sound that way. Stupidy tries to account for real-world instability, chaos, structure, the stock market, virus propagation, shipping delays, funerals.
      It’s also about individual numbskullery, and the ability of one person’s tragic flaws to be inflicted on billions of others. And it’s about the creation, adoption and propagation of all technologies, not just those for information transfer.
      ~
      But in addition to wtf, randomness, chaos, and interconnectedness, stupidy is also an attempt to describe just how wonderful life can be.
      The more things we humans do, the more amazing things we do, right along with the terrible. What makes that happen? Sometimes, it's good. Sometimes, life gets better.
      Why is that? What kinds of things, not a specific list of things, but what kinds of things? Is it options, restrictions, emotions, pets, trust, lasers, I don't know, nobody does, not yet—what makes life wonderful?
      And how do we make that happen more often, for more people?
      ~
      There is a branch of stupidy research which is basically the theory of mad scientists, lone gunmen, Oklahoma City bombers, even ordinary people who might participate in an outright assault on the very institutions they claim to support.
      It's also the study of the one-hit wonder, the pet rock, handlebar mustaches, and hand symbols that appear from nowhere. Suddenly we have a new thing, that never existed. It can actually save lives, and help people cry out, and be rescued from trouble. And it rises up on fucking TikTok.
      It's the study of prophets and madmen. Saviors. Terrorists. Ideas that change the world in one single instant because suddenly things snap into focus and, how did I not see that before? The branch of stupidy research I'm talking about here is not devoted to studying their worlds, their words, their ideas, that's a separate specialty.
      This branch is about how often, and where, and when, these things might arise. And what is the relationship between this new thing, and what is already here. Is it going to push back, is it going to build up, is it going to tear down, is it going to connect, is it going to drive apart.
      The kind of change can be reasoned about, even if you will never be able to predict the change itself. Sometimes, that change makes everything better.
      It turns out, it's remarkably useful to be able to describe the likelihood that one person, working for years, alone, to make something that is suddenly unleashed on the world and causes untold joy or havoc and destruction. We can't know who, but we can reason about how many, and what groups are vulnerable, both as victims, and as recruits. This is absolutely not a new problem, but now, we are just starting to get the tools that let us work toward understanding these things the way we do quantum electrodynamics or blackjack.
      As well as quantifying—not specifically, mind you, this is not Isaac Asimov's Foundation—the level of havoc and destruction we might be talking about. You can't know who the madman will hate, but it will be someone, and harm will be inflicted somehow. Stupidy helps you reason about the spread, the magnitude of the damage, both for the ideas and the physical results. More technology means more energy, more options, available for crazy shit to happen. Each of those things can be modeled and estimated.
      Because, it also turns out, even that lone madman is still tied in with the rest of us.
      There is no such thing as just one human.
      ~
      It's not my fault the best measure of the potential for greatness and misery in humanity is something called "stupidy". That's just the way we are. And we love it!
      Stupidy helps us work through the details and implications of just how much, and how, we love, absolutely love being human.
      We love eating and fucking and making things and raising kids. We love talking about it. We love telling stories and hearing about what other humans are doing. We make art, we have newspapers and TV, we post on Twitter and Facebook. We copy things, by hand, letter by letter, in gold leaf. We put our hand to the wall and blow the ochre dust. We leave a mark.
      And every time we do that, some little bit of us is shared.
      Sometimes it's toxic, like when you hear that sharp crack of dad's leather belt, and you are four, and all you know is that it is time to scream in terror, and, soon, to scream in pain. You can't possibly understand, just what you, personally, could have done, to deserve the blows you know are coming, and are helpless to prevent.
      Sometimes it's just that little smile you can see in someone's eyes above their mask, the one that says, I see you and I understand, and it sucks, but it's OK, we're all here in this together.
      Every one of those moments leaves a mark. Every moment is a communication.
      We're all communicating, all the time, we're all telling stories.
      We're all inventing this reality we share. We make it up as we go along.
      ~
      Your thoughts didn't happen in a vacuum. I think the most incredible thing I have ever experienced in my entire life is watching my son's brain stitch itself together. He couldn't even focus his eyes when he got here!
      And at first, you can see where everything is coming from, because you're right there, all the time. When he stands in that little washbasin in the bathtub and says "pool", you know the actual pool he means! And the moment he first experienced it.
      But you can't hear, or see, or prevent, or change, or save, from everything. Experiences go in and mix with our genes, our environment, everything around us, our physicality. And right from the start, we turn into something completely new, something that cannot possibly have ever existed in the entire fucking universe, right there.
      Every single human. Every one of us.
      Little babies, eating sand and crawling backwards, our fist in our mouth, grabbing our toes. Even the biggest fucking asshole in history.
      ~
      Think about it, picture it, grab hold:
      That person you despise, that person that just really fucking pisses you off, that bitch that stole your idea, that asshole that almost got us all killed, the vortex that fired you and took your home and security, every single one of those fucking assholes, those fucking jerks, those goddamn shitheads, every one of them—
      —crying, so tiny, so helpless, so mushed up and red and wrinkly and squinty eyed, there in your arms, you can feel that blanket and oh my god, what if they just stop, what is keeping them going—those fingers, those fingers, those tiny, tiny fingers—how can they possibly be right here after all this we went through, and now it's all on me, I have to take care of this little fucking asshole—
      That's everybody. We all have to take care of that little fucking asshole, because that's us.
      Those fingers are so fragile. That little heart could stop at any moment.
      How big is a billion? Sometimes, I think of it as, we get a couple billion or so heartbeats, and then it stops.
      ~
      Every single heart that stops, every single agonizing, lonely, hurting, scared death, every single one. Every person whose flesh rotted away beneath them because they were trapped and couldn't escape, from chains or quadriplegia. Every person with a feeding tube.
      Every person on a ventilator that's their own goddamn fault, with metal and plastic jammed so far down their throat they need to be sedated or they'd tear it right out, screaming in agony.
      Every single person who just stops living and there's nothing there anymore, no light, no movement but the slow churn of rot and renewal—and those eyes staring blankly, or gouged out, or shattered, or vaporized, or full of tears—
      —or full of stars and wonder, right there, just at the very end, because finally, finally, finally, oh look can you see, just look—
      ~
      Every single one of those deaths matters, because someone held that little baby, at least once, and even if the person that held that infant is gone, now, and they too died lonely and forgotten, they still mattered, once. Just like me. Just like you.
      Do not listen to that voice in your head that says you do not matter. You matter. You are not alone.
      That voice is a lie, it is the lie the vortex will tell you so it can consume you and discard you. It is the story your head constructs to explain just why you deserve what life gave you. Fuck that.
      This is our sacred duty, this is literally the only thing that matters, listen to everybody who's ever said it with more talent and art and amazingness than I ever can: We have got to be kind.
      ~
      Some of the equations for working with stupidy come from biology.
      If you look at the earth at night, from high above, you can see the cities lit up, along the coasts, stretching inland, coalescing in spots, scattered elsewhere, looking exactly like mold. This is not accidental or mysterious, it's how things spread, whether fruiting spores, or taverns and pogroms and churches.
      This sight is what changes astronauts, by the way. It is what turns them into actual different people, when they come back down to earth. That mold could be scraped right off.
      ~
      The same relationships, once you describe them in symbols—and their relations to each other also described in symbols, this is what we mean by "math"—will also describe the rate at which a population of insects on an island 40 feet in diameter will diverge from, and occasionally be refreshed by, nearby tiny islands.
      We do this based on what's there now, how close the islands are, the temperature of the water, the air, the wind, everything else you can measure and quantify and hypothesize and reason about.
      We can't say, not yet anyway, specifically how that population might diverge, just what kind of crazy shit nature is going to get up to. But you can talk about things like how often new spores—or ideas, or terrified little bugs trapped on a floating leaf—make it over from place to place. And you can look again, and again. Which is science, just going over and taking another look at that island, and verifying the story someone else is trying to sell you about what is going on over there.
      You can also talk about, and describe, with symbols, things like competition—because each of the bugs has got to eat the same food, one way or another—and defenses, and weaponry, and fear. We spend a lot of time, a lot of science, looking at this stuff. This is economics, this is biology, this is the stock market, this is politics.
      This is mass murder, genocide, slaughter. That shit does not happen in a vacuum.
      ~
      Quite often, when humans have decided, this is a good time to kill each other in extremely large numbers, it's because we need physical stuff. It can be other things, like pure and simple greed, or tribal bigotry like religion, but most reliably, it is because we are starving. Our babies are dying, you can see the light going right out of their eyes. So we get the fuck up and go look for something better.
      At first, we could just go somewhere else, and there wouldn't be any other people, so we didn't have to worry about that, there is new land everywhere and we can go there and live our lives. I don't know how long that part lasted, but it probably wasn't more than a few tens of thousands of years at best, a blink of the eye, that occurred long in the distant past. Neanderthals were people, and whoever they pushed out, were people, too. If you can stand up, and walk around, and use tools, you are people, to me.
      If you can stand up, and take care of those who cannot stand, you are people.
      This is everyone now, everywhere you go, on the entire planet. Think of it. We move fast. We covered the globe in an astonishingly short time, and took up all the places. And then started working in on the people who were in our way, which is, of course, everyone. I am sorry, other people, but you are not my family, and I need what you have.
      Personally, I am really glad to be living here in the present, where there aren't any impending changes to where people can live. Two separate towns where I lived have been totally destroyed by historic natural disasters. I hid from the tornado that destroyed Xenia, and now Paradise has burned to the ground. Which is a completely normal thing that has always happened.
      ~
      None of this is even unique to humans! This is how nature works. Everything is in flux, all the time, and one of the reasons we are good at sticking around, is that we can adapt. We can adapt to anything. History is quite clear on this.
      But what we desperately need to adapt to—we are having trouble, but getting better, so slowly—is the fact that other people are family, too. That's the great arc toward justice I was referring to.
      The ability to treat someone you've never met—someone whom you have no idea how they see themselves, their hopes, their dreams, what they like to be called, their ability to stand on two feet or be trapped in a wheelchair, what they eat, how they talk, what they think, how they live—the ability to treat someone as completely alien as that, so completely different, literally, completely unknowable save for one thing—the ability to treat random fucking strangers with the same bit of kindness you'd extend to your own dog, or grandmother. That is what society is.
      That is government, that is politics, that is media, that is education, that is music, that is art, that is religion, that is philosophy, that is science, that is economics, that is everything. All that exists for one, single, purpose: To keep us from cutting people's heads off, and shitting down their throats, so nobody else can ever fucking come near our family ever again.
      Our ability to grasp this, and make things better, rather than worse, is based on our ability to know, and talk, and share.
      ~
      When I say that Mark Zuckerberg has specific, personal, individual responsibility for being a fucking asshole, I don't say it lightly. He was naked and screaming and terrified once. Maybe that's just another Friday night. I cannot judge those kinds of choices, because I am not him. I didn't grow up in his shoes, have his life. Because if I did—and this is absolutely fucking crucial—I'd be him.
      So where do I get off, calling out one individual human, when I've just gone on and on about how we have to be fucking kind?
      Because there is the slightest, tiniest possible chance that he might read this essay. I am not kidding, that is literally why I am writing this here right now. This is the delusional part.
      I want other people to read this. I want them to adopt the ideas. I want people to talk about them and run with them and make them into other ideas. I want people to talk about it until he can't ignore it.
      I want Mark Zuckerberg to read this.
      I want him, personally, to know what I, personally, think is important, and how important I think it is.
      I know this is extremely unlikely to happen in anything any ordinary person would try to describe as reality. But who knows? I have decided, I am done with ignoring impossible problems. Maybe I can make a difference. So—
      ~
      Mark Zuckerberg is, absolutely, a giant fucking asshole, and possibly the biggest in history.
      He could change that—if he thought about the rest of us for one fucking second, instead of himself.
      He could change that—with humility. A belief that you know more about what is right for the entire rest of humanity, all by yourself? This does not sound humble to me. And this situation, right here? Is literally what humility was invented for. Not all that other shaming shit we do. This, right here.
      So, Mark Zuckerberg could change his current asshole status, all by his lonesome.
      But if he does not, history will not treat him kindly for what he has done with what we have all given him.
      ~
      When you build something as big as Facebook, you can't do it by yourself. I've tried, you need other people. And the people who want to work on something like that, are, improbably, interested in what they do for a living.
      So in addition to hiring people that can solve the problems you set out for them—keep the machine running, keep the money flowing—those same people have often thought long and hard about just what they're building.
      And to build something like Facebook, you hire a lot of people.
      You hire software developers, artists, writers, groundskeepers, electricians, salespeople, sysadmins, cable-pullers, heavy equipment operators, pilots, plant managers, supervisors, planners, project managers, editors, videographers, grips, directors, admins, associates, interns, temps, contractors, agencies, doctors, and so, so many others.
      You also hire scientists. You'll hire these insatiably curious people, who are absolutely fanatical about the value of truth and communication and sharing. While they're looking into the things you tell them to—please make as many people as possible look at Facebook all the time, every day, constantly, ideally every single human in existence, thank you—they will be thinking about the things they are doing.
      They'll ponder, and hypothesize, and talk it over with each other. They'll design experiments and do studies, because this stuff is really fucking fascinating!
      And also, this is what scientists do, they're like ants, they can't help it. There is no such thing as just one ant, or just one scientist. Ask the tobacco industry, or the fine folks over in geological resource extraction. You hire a bunch of scientists and the next thing you know, they're telling you the actual truth about reality, whether you like it or not.
      So, it turns out, given a historic opportunity to poke around at things like stupidy, even if they didn't call it that, a bunch of scientists are going to do a shit ton of research on it. And, being human, they'll notice stuff.
      And, being human, they'll try to point it out. To the only person who can possibly do anything with it: Mark fucking Zuckerberg.
      ~
      He owns Facebook, he controls it, he decides its policies, he decides its name. He decides how we can even refer to it, personally. A thing, used every day by billions of people! A structure built on the efforts, the experiences and joyful creativity and bitching and everything else, of billions of people.
      He has consistently, single-mindedly, dedicated all his efforts to increasing his own power and control, and has deliberately decided, fuck science, fuck humanity, fuck all you motherfuckers. I am getting mine, and I am going to keep getting mine, forever, and you cannot ever, ever, stop me.
      He knows, first-hand, in ways we cannot, how each of his own decisions has led to lies and anger and hatred and death. He has the actual science to back it up. And he does not give one single, solitary, fuck. He likes it that way.
      He likes it that way. This is what he wants. Given a choice between his power and the right thing, he has always, always, made the right choice for him, and the wrong choice for the rest of us.
      ~
      There are a lot of shitty people in business who have done or are doing shitty things because they're fucking assholes, and some of them may even later do good things. I'm not talking about them, because, while what Bill Gates did was greedy and vicious and predatory and harmful, in the end, it was just Windows, and technology moves on, it always does. IBM used to be everything, then it wasn't, then it was, then it wasn't, and now they make robots that play Jeopardy.
      But Facebook is unique. It is the first time in history we've had a chance to take a look at stupidy, good and hard, with lots and lots of real fucking numbers. We have a unique opportunity to examine stupidy, and learn how it works, in real life, and what it can do, and how fast it grows. Again, I am not talking just about the toxic stuff.
      ~
      Facebook has data, talent, experience, and curiosity. The people there want to help literally the entire rest of humanity.
      And the vortex at the very top is saying, nope. I need that billion.
      You can't use that billion for research, I need that billion.
      We can't afford to take measures we know for a fact can help make the world a better place, because I need that billion.
      I have not yet monetized every moment of human existence, forever. So for now, we must prioritize growth, and I need that billion.
      I need that billion, because my soul is a vortex, a howling, gaping maw, hungering and hungering.
      I need that billion, because you can never, ever stop me from getting what I want, which is literally everything, everywhere, for all time.
      I need every billion.
      ~
      The study of control exerted by one person, how that propagates throughout society, that's part of stupidy research, too. While you can't group together the actions of dictators, mob bosses, preachers, billionaires, and other riff-raff, you can reason about how many, and at what level, and in what relationships to others, these actors occur.
      And you can reason about the sorts of things people always do, every fucking time, every single fucking time, they get some money or power, even if you don't know, specifically, the things that technology, or their social connections, will enable them to get up to.
      Like entropy, stupidy increases. More connections, faster idea propagation, the higher probability that wonderful ideas and toxic ideas are going to spring up and then be given room to grow and mutate and propagate just like COVID.
      We can't know what toxic beliefs—or amazing things!—are going to happen, but we are right at the historic beginning of getting the tools that will let us get to a real consensus about how to talk about and deal with these things, together, all of us, as a society, because these are incredibly hard problems, impossibly hard, and they affect each one of us and the way the future is going to turn out.
      We could be working together, right now, building and learning, and making mistakes, and trying to do the right thing. And it's his, personal, specific, individual decisions that made Facebook what it is, and what it means to us, and what we are allowed to investigate, and regulate, and make better for everyone.
      Through all of it, he's been right there, trying to crush the truth about what Facebook is doing, and therefore what he is doing, and tell us all to shut the fuck up and get back to giving him all our time, attention and money. He could make different choices, ones that help the rest of us, rather than just himself.
      ~
      Because the other part about Facebook, is that it is fucking amazing.
      We need it! All that love, all that joy, all that stuff about being human, all that increases as stupidy increases, too!
      I've focused on the bad here, but that's only because the bad right now is pretty bad, and I'm ticked, because the good could be so incredibly amazing.
      I still believe increasing global communication could help us all be better. I believe it. I believe it, I believe it, I believe it I believe it I believe it I believe it, and it will happen, eventually.
      ~
      If it hadn't been Facebook, it would have been something else. I want to be extremely clear about this.
      Mark Zuckerberg is actually not special, not in the way he thinks. Given the power he exerts, if you compare the amount of talent, versus luck and being in the right place at the right time, and standing on the shoulders of so, so many others, Mark Zuckerberg is basically the guy who is rich because he was standing outside, and had a bucket handy, when it started raining money. It can't be any other way, it takes too many people, too many connections.
      In some hypothetical other reality, both he and Facebook have got different names.
      But here, it's Facebook.
      And Facebook won't last forever, we will keep at this whole communication thing, iterating and trying new things, making new networks and ways of being human.
      But our world is suffering, right now, and he could make different decisions, and maybe, just maybe, he'll listen, so—
      Fuck you, Mark Zuckerberg.
      Think about one single human besides yourself for one fucking second.
      You fucking, fucking asshole.
      ~
      Note—
      Exploring the intricacies of why, to effect actual change in this situation, this essay depends on the choices of just one individual human—and how you might model, and reason about, the transformations to reality which you'd need to apply, to effect a change in that—are for another Sunday post. Even better, an exercise for the reader.
    The Sunday post
      With apologies to Smullyan, this is not the post referenced in the title of this post. That one's going up in a few hours, and when you read what it's about, and what I'm really trying do with it, you are going to say to yourself, "Huh, so that's what full-blown delusion looks like." No joke.
      It'll be about names, among other things. I recently discovered the perfect name for something, its creator agreed, and now, forever, that thing will be called Drumkit. I spent five minutes thinking about it, and suddenly I have shaped human history, without even trying. I am not going to lie, that feels pretty good. I will probably chase that high for the rest of my days.
      I spend a lot of time thinking about names, actually. I've been paid cash money to think up names, I have written software to help generate names, that's how much I think about names. I'm also lazy and stupidly literal-minded, so sometimes I will base an entire series of novels around chasing a goal which the characters actually call a "macguffin", and in fact, are being chased around by THINGs, and, well, there are some other names in there that I'm not quite ready to disclose yet, because I think they are both brilliant, and so, so, stupid, like most of the things I come up with.
      That project, in particular, is pretty emblematic of everything else that goes into making up the blog part of what I'm doing. It's something I've been working on for years, since April, 1994, actually. There's a particular concept around which everything revolves, and I've spent countless hours thinking it over through the years. In particular, there are a couple key notions, and to work with them, identify them, use them, I've given them names.
      None of this work is really public, yet, but I've talked it over with coworkers (ok, dropped into unrelated contexts for no good reason, but still), and awhile back, one of them suggested a name for something. And this name is perfect. It is obvious. It is so clearly the right name, that you cannot deny it. You will agree how blind I was not to see it. This name is so fucking perfect, I haven't even decided what it actually refers to yet! In a project I have thought about literally every day, in one form or another, for three decades, it was staring me in the face, and I never saw it.
      I wonder how many other things there are like that.
      Anyway, I'm not ready to write about that project yet. Instead I'm going to turn to the Loaf Question. Which I'm also not ready to write about yet, so I'm going to keep it a mystery what that project actually is referring to. If you are curious, go read the forum thread. It is not long, it is presented as a puzzle, and if you know anything about the history of computing, you will absolutely recognize the project and the madmen I'm going on about. No joke.
      But since I know you are one lazy motherfucker, I am going to paste in one little bit about names, because names are on my mind lately.
      Tumbling through the names
      As I've mentioned before, the creators of the contraption were extravagant with the names they bestowed on the various parts of the beast. Snarf. Ent. Turtle. Flock. Bert. Orgl. Crum. Waldo. Enfilade. And, of course, Loaf, among many, many others.
      These names got coined and evolved over four decades of development. When they built a new thing, they gave it a new name, partly to help solidify its literal uniqueness in the world. So, Fossils and Recorders and OTrees and HTrees and the Granfilade and the Poomfilade and the Bert Canopy and the Sensor Canopy and the DagWood.
      By the time they began work on the version of the beast I'm currently exploring, I think they started wondering how well these names would resonate with those who they hoped would use their creation to build even more wonderful things. So they changed some of the names once again. Orgl became Edition, Bert became Work.
      It's a little sad to see those names go by the wayside since they'd been used for so long, but I think saying you have an Edition of a Work is much clearer than saying you've got an Orgl of a Bert. And anyway, the names live on via the internal structures of the thing, so that's nice. (For example, we still have OrglRoots and the Bert Canopy.)
      However, in at least one case, I'm thinking about turning back the clock.
      This project has for decades had the concept of an infinitely expandable number space. Like 1.25.0.0.0.33333.92.42.2021.0.5. And the math to go with it—you can take two of these things and add them, subtract them, do all sorts of nifty things with them. They've long been used to carve out a way of addressing the smallest chunks of the secrets given to the contraption, even across multiple machines.
      When I was much, much younger than I am now, I read about these mystical things and loved them. Part of the reason was what they were called: "tumblers." The name evokes many things, from acrobatics to the clicking of the inner workings of a lock (or a bank vault!) as the key is rotated into place. The idea that something so serious and powerful could have such a playful name appealed to me.
      So what are they called today? "Sequence." Um. Yeah, sequence, whatever. Sure, the literature defines the term as "an infinite sequence of integers," so I suppose the name makes some sense.
      But to me it's still a tumbler.
  November 13
    It comes straight from the top
      (8 min read)
      I just made a quick edit to something I've written previously. My struggle with that concept is covered elsewhere here, but I thought this is a good example of the kind of edit that I have given myself permission to do, so this is actually about the edit itself, which was to fine-tune a joke.
      If this were another essay, it would be about how I should just transclude the node I'm pointing to, rather than pasting the text here. That essay would emphasize the importance of being able to specify precisely which parallel universe I want to quote, because I could later edit that node to say something different. That essay would explore the Loaf Question, as well as some of the ideas that actually animated that infernal machine.
      If this were another, other, essay, it would be a riff on Hofstadter's musings on counterfactuality. In the process it would probably veer off into Minsky's A Society of Mind. But that essay would probably get back around to the Loaf Question, too, through all the usual routes like Vannevar Bush and As We May Think. See Intertwingularity, under Hofstadter, under Reality Recursion, under Phil K. Dick.
      This post, however, is not about infernal machines. It is about how leadership works.
      Here's the edited gag:
        Anyway, it worked pretty good for movies, but for actual TV the VCR was a complete fucking disaster. It was so bad, entire swaths of the economy were devoted to writing and performing jokes about setting the clock on the VCR. It absolutely eclipsed the airline food sector, destroyed rolling up the toothpaste tube, and came close to unseating relentless, horrific sexual harassment, like that featured during the Henry Blake era of M*A*S*H, as the top source of quality jokes.
      I thought about this edit for a few days before making it. I added the words "during the Henry Blake era".
      I'm working on a big post, which I've decided just now to call the Sunday post. This means I have to post it Sunday. It also means, I think it's important enough to think about rather than posting immediately. It also means, I can't weasel out of it, since now you know it exists. It also means, if I feel like doing something like that again, I have just invented a new thing that I can do, and a place to do it, and a way to refer to it.
      This is one reason why names are important, it gives us something to grab hold of. That post will explore the importance of naming something, but it probably won't actually get around to that, not explicitly anyway.
      That post is also going to make a big deal about leadership, but it is already far too long and about too many things. But I wanted it to be absolutely clear that when I say something is due to the way things are at the very top, I really, really mean it. So here we are.
      I'm working my way through M*A*S*H on Hulu, which has been a great experience. One of the things I do is, I try to be funny. I think humor can, better than nearly anything else, faster, help us to see the world in a different way. Those little bursts of epiphanic clarity can instantly reshape how we think things work, better than nearly anything else.
      The laugh itself, is completely involuntary. We can't help it, something just made us gasp, did you see what just happened there? That shit was hilarious!
      How does it do that? Is it the words, is it the drawings, is it the voices, is it the timing, is it the editing, is it the material, is it the contrast, is it the pathos, is it the rhythm, is it the repetition, is it the slap in the face, is it the pie? What is it? I want to do that.
      I want to know how it does what it does, because laughing is amazing and I love doing it, and, crucially, I crack myself up, sometimes. And I'd like to know how to do that more often. I am sorry. Sometimes I think I am one funny motherfucker. This lasts exactly long enough for me to realize that no one is laughing, and then I go do something else for awhile to hide my eternal burning shame.
      I am not kidding. This is part of why I have literally hundreds of projects going, all the time. If I'm posting animations, it is because I have humiliated myself with words and need to try something completely else, or else I will crush my own soul. I am still trying to come up with a name for that refractory period between the mistake that makes me set the project aside, and when the humiliation has subsided enough that I can try again. Probably something horse-related.
      Anyway, everybody knows, M*A*S*H is fucking hilarious, and it is hilarious for exactly one reason: There is no laugh track in the operating room.
      We all know that, so I won't belabor the point. The contrast between a show that could do serious, and funny, was what made it all poignant, it was the little swirl in the yin-yang symbol that tied it together. Everything else sprang from that, it is the foundational genius insight of that show.
      The laugh track drives me nuts and I wish someone would convolute it the fuck out of there, because it's repetitive, and that's what convolution is for, but until someone does that, I'll take the bad with the good. (Like the cropping in the Hulu release, which is weird, but I can get used to it. It did ruin the joke where Frank Burns sticks his finger out of the crate like a little periscope, but I knew the gag anyway, so it's all good.)
      So the show is basically one hundred percent, all the way through, to its bones, about the idea that there is horror in the world, and part of how we deal with that horror is trying to be human, and funny. And comedy, the best comedy, the stuff that really gets you, is fucking horrific.
      You may think I'm going to be all Lenny Bruce or whatever the fuck here, but no, I am not talking about people like Dave fucking Chappelle who think they now get a pass for whatever lazy-ass offensive, degrading shock shit they want to spew and rest on their existing, documented brilliance. (I say "whatever lazy-ass shit" because I don't need to watch Netflix to know what he's been up to, I can tell it's fucking offensive, I can hear trans people when they talk, did you know they have voices and reasons for why they say things, just like every other human ever.)
      I'm talking about the stuff that you can't unsee, once you've seen it. NO NOT LIKE THAT NOT LIKE [EXTREMELY DISTURBING INTERNET GOTCHA PAGE REDACTED] WHAT ARE YOU KIDDING ME YOU LITERALLY CANNOT UNSEE THAT WHY WOULD YOU EVEN DO THAT TO PEOPLE I AM NOT KIDDING
      Also, I'm not talking about the stuff in M*A*S*H about how they tie their masks. I don't know what happened, but sometime between then and now, I gained a whole bunch of judgy opinions about how masks should work, and once you've seen that in the O.R., you can't unsee it, either.
      In the first few seasons of M*A*S*H, the jokes that aren't about the horrors of war or racism or whatever, like, nearly every single one, and this is one funny show, so there are a LOT of them, every single one, repeatedly, right there in your face, is because it is absolutely hilarious to repeatedly, constantly, unrelentingly, obsessively, at every single opportunity, every moment, every thought, never stopping, sexually harass every single person you see.
      This never stops. It is constant. It is absolutely hilarious, and most of the gags revolve around the indignance of the ones subjected to the harassment. It is demonstrated, constantly, all the time, in every single possible way, that this is the way it is and you have absolutely no fucking recourse. The very idea that this isn't the way it could be, the very concept that you deserve one fucking bit of basic human respect, THAT is the joke.
      Hawkeye and Trapper John are relentless in their attempts to deal with their absolute lack of control over what's going on around them by forcing their sexuality onto literally everyone around them, nurses to Radar to Klinger to Koreans to the wounded. Nobody has a say about any of it, they must participate. (That is, of course, the joke.)
      Henry says, aw gee, come on guys, don't be like that.
      He's married, and he gives nurses little kisses on the nose when they get their underwear from his tent, so he can't really throw stones.
      Colonel Potter would not put up with that shit, not at the levels maintained during the first few seasons. There are other reasons the show changed then, it moved to sets, it was edited differently, the characters changed. But it was still funny, it was fucking hilarious, and it stayed funny for a long time after.
      Colonel Potter would not put up with that shit, and things changed. Things were still good, we didn't lose anything. They were just good in a different way. We don't lose out when we prioritize basic human respect. As a commander, you can get things done with your crazy doctors, even if you rein them in. BJ did not, in fact, make things funny by constantly making everything about his own desires and lack of control over them. As a creator, you can still be funny and make jokes about power without making every single thing about sexual humiliation.
      Colonel Potter would not put up with that shit, and things changed.
  November 12
    Another bottle episode
      (13 min read)
      I can't stop thinking about just how incredibly stupid this idea really is. When I get done describing how stupid it is, you're going to say, why yes, Gary, that is the stupidest fucking idea I have ever heard, and, in fact, you have succeeded in making it even more stupid than I already thought it was, and that was pretty fucking stupid.
      I'm referring, of course, to this little gem:
        This code depends on the standard environment to sanitize data.
      I guess the reason I can't stop thinking about it, is that maybe it's just stupid enough to work.
      To review, I'm describing a hypothetical place in the cloud where I can put little snippets of Drumkit code, and call them when I need them. This implies a few things, most importantly, a virtual machine in the cloud that is executing my Drumkit code, and some sort of supervisor/traffic router that knows to how to start up the virtual machine, or wake it from sleep, route requests to it, and send the responses on toward their final destination.
      Here are the pieces we are talking about:
        The client
          The client is going to call my Drumkit code snippet. This could be Drummer, another snippet, a browser, etc.
        The traffic router
          The client sends the request to the router, which is a service that runs in the cloud, and is actually the public face of the universe. The router inspects the request and identifies which universe should handle the request.
        The VM
          This is the actual universe in which my Drumkit snippet runs. It's a virtual machine. Normally, in this type of scenario, this is where any input validation and cleanup occurs.
        The standard enviroment
          This is a separate process, in a separate VM, which runs the input validation and cleanup code.
      I should be clear about the exact problem I am trying to solve: I want that snippet to run literally forever, until the end of time. I am not kidding about this. When I talk about how you should go see what Vernor Vinge says about how software ages, this is what I mean.
      Here's how it works now.
        My snippet is running in the VM
        Input is handed to the VM
        As part of the handoff to my snippet, there is actually a long series of calls before it gets to my code. This is all in library code. It's doing things like unstitching arguments, repackaging things, and, critically, sanitizing input.
        All that code is executing in my process, in my VM, because that's how it works. The call can never get to my code unless it can be processed by all that other code first.
        If a security flaw is found in that library code, it needs to be fixed. The dream is, the library code gets fixed, the VM environment gets updated, and now all that code that processes my requests is up to date, and runs properly, in my VM.
        Sometimes, fixing these things means that the maintainers need to break things. That library cannot possibly be fixed the way it works now, we need to change the way it works. Because that code calls my code, and my code calls that code, my code needs to be updated, too.
        If my code doesn't get updated, we have a problem. There is a security flaw, which means it isn't safe. So we can't launch it. If we do try to launch it, it will crash, because it is no longer compatible with the new, safe environment.
        My code wasn't at fault, my snippet was fine. The security flaw is somewhere else entirely, but suddenly, anything that depended on that snippet stops dead in its tracks and starts throwing exceptions.
        Or, maybe, my code was at fault. It can't handle the latest version of UTF encoding, or something. Either way, my snippet can't run because it can't be trusted to properly handle the input.
      So instead, I'm proposing that the input and validation code all runs in a completely separate process, that can get updated whenever, because all it has to do is one thing: make the input safe. For lack of a better name, I'm calling that process the standard environment.
      Obvious objections why this is stupid
        If you are writing code, you need to be working with the latest standards and libraries, so you should keep up.
        This is less efficient, because now we have a whole extra process in the way.
      The first objection is valid, but only for code that is actively being maintained by someone who can literally drop everything and fix it when the cloud environment gets updated. That's basically nobody who isn't a team of developers for any non-trivial project. And when I'm dead, who's going to maintain my snippet? That's right, nobody.
      Because even if that snippet is so incredibly brilliant and useful that a whole team of people have stepped up and are keeping it up to date, this is how open source works, guess what kind of people do that? People who like to make things with software. I am one of these people. And we may like tinkering and keeping things running, but what we really like is making things better, and sometimes the best way to make something better is to make a whole new thing. So that little snippet will not be running forever, it will stop spinning eventually, when enough people stop caring.
      The second objection is valid, and is the really, really stupid part. Because what I am proposing is so monstrously stupid and wasteful, I am going to once again, apparently, take someone else's brilliant obsessions, and turn them into an electric toothbrush you can also shave with.
      And sometimes, the ideas I am rummaging through are so brilliant that so many brilliant people have spent so much time thinking about them that other brilliant people have written books with hundreds and hundreds and hundreds of pages just trying to summarize them and tie them all together, and quite often, this results in a cannot-put-down must-read.
      So, spoiler—
        Go read Gödel, Escher, Bach, by Douglas Hofstadter, and then come back here.
        If you have any interest at all in the recursive nature of reality, the way ideas work, the way music can reach deep inside you in ways that are literally mathematical, and how that could result in a record, made by a turtle, which, when you play it, causes your record player to explode in a shower of brilliant engineering, or how to talk to a colony of ants, or so, so many other things, it is worth the effort.
        I'm not kidding, it's a lot of pages, but if you did in fact lose your mind and listen to me and do what I suggest, and go read that book, and then come back here, you would, like that guy in Hellraiser 2, when he got back from his little journey, say to yourself, with wonder, "To think I even hesitated." No joke.
      Right, so I am deeply concerned with the idea of attacks from parallel universes. (Well, in fiction, and metaphor, I am, I'm not literally of unsound mind, work with me here, people.)
      Recall that my snippet is there, spinning away in its own little universe. And its only real problem is that it can't handle certain things, it literally can't adjust, something comes along it wasn't prepared for, and kaboom, there it is, useless, and so it stops spinning.
      But why is that? I've described some of the things that keeps software from spinning: inertia, change, interest, progress. I think it's literally impossible to expect that snippet to be maintained in the long run. The long, long run. This is just the way humans are.
      What if I take the humans out of the equation, though? Are there any other reasons why I can't keep that snippet running forever, useful, somewhere, doing what it was supposed to do? Well, it turns out, yes, there are. And you can prove it with math. That's why we needed the humans to do the maintaining in the first place.
      Here's the gist: If you try to make a system that can handle everything, that system will not be able to handle things which are not described fully by the system. Which, it turns out, is the system itself.
      BOOM.
      If you have never encountered this idea before, and something just jolted into place for you, that is what we call an epiphany.
      Let's try again, using one of Hofstadter's examples.
      Here's how a record player works: On a record, there are tiny grooves. The grooves wiggle from side to side, and the wiggles are exactly analogous to the vibrations of sound waves. As the record spins, we drag a very small, delicately suspended diamond through the grooves. The wiggles in the grooves make the diamond wiggle.
      We have sensors, tiny electrical generators, usually, though there are other ways. We use those sensors to turn that physical vibration into electricity. The electricity wiggles, it varies the same way the diamond is wiggling, which is the same way the grooves are wiggling.
      We use that electricity to drive motors, which is what speakers are, they're small electric motors, like in your Tesla. The speaker surface, usually a cone, but sometimes flat, wiggles due to the motor. That pushes the air around, and so we get music.
      When you strike a bell, it rings. If you strike it again, it rings with the same tone. (If you want to make melodic music with bells, you need a lot of bells.) This is the bell's natural resonance.
      If you strike your record player, it will ring like a bell. That is your record player's natural resonance.
      If you make a record that includes vibrations that are just like that resonance, that record player will do something it was not intended to do: It will make those vibrations stronger than the ones you want, because the record player will start to resonate. Which is to say, it will vibrate. And if you vibrate something enough, it will start to shake. And if you shake it enough, well, pieces may start flying off.
      BOOM.
      We have a record, which, when played, can cause your record player to explode. It won't work on my record player, because mine is different, and resonates differently. So I am totally, one hundred percent, safe and secure from this attack. I can play that record all day long. (In fact, if you brought your record player over here, and I played that record, long and loud enough, I could probably explode your player without even touching it. But that's not actually the parallel universe attack I'm talking about here.)
      My point is, my record player is safe from the record that broke yours. But you can easily create one that will break mine. This is a problem, but it's OK, I can work around this. I can add something to my record player that changes it, now it is no longer vulnerable to that record.
      But now, it is vulnerable again, to a different attack, because it still has the same problems it had before. I can't get around it, you will always be able to make a record that will cause my record player to explode in a shower of recursive good intentions.
      You can prove this with math and logic, and lots of brilliant people have built on each others' work through the years to figure this out. It is literally impossible to work your way out of this problem.
      So my goal, of keeping that snippet running forever, is impossible. You can work it through on the whiteboard, if you have one big enough, to go through every single point of failure that will keep that snippet going, and plan around it, and every single flaw you identify, every single mitigation you come up with, given enough time, someone can find an attack that will render your preparations useless.
      I'm tired of giving up on impossibly hard problems. Just because I can't solve it doesn't mean I can't make things better, so here goes.
      Instead of patching up my snippet, keeping it up to date, the standard environment is a separate process, a wrapper if you will, that intervenes, and filters, and keeps safe. You can't do this forever, because each snippet is unique. You will need to make a lot of variants on the standard environment. But, each snippet runs in a particular universe with a particular set of assumptions and flaws and resonant frequencies, and actually shares those assumptions and flaws and resonant frequencies with a lot of other universes. So, much of the filter that helps my universe, could help yours, as well.
      This is so not the same as keeping the libraries up to date in your VM, I cannot over-emphasize it. This is not maintaining the VM. In an AWS Lambda scenario, this is not keeping your node.js library up to date. This is not even keeping the virtual machine that runs the VM that runs the node.js that runs your code, up to date. This is a separate, new layer, that goes in between those things. It's an entire, actual, separate process that runs independently. That's how stupid this idea is.
      But wait, it gets stupider! I am assigning a lot to this here little "standard environment", in fact, I'm giving it a pretty impossible job. Some attacks are sneaky. Many, many kinds of attacks involve tricking your machine into thinking one kind of thing, is actually another. One of the ways you do that, is you disguise what you're trying to do. You fool the guards. You have an escape, you can get away with this and they'll never know. See above for why. You can render your attack literally invisible.
      How this works is, you obfuscate. You scramble. You try to mix up the layers. If warning signs and critical instructions are in red paint, you will use red paint. If you have something that is, obviously, at first glance, very, very bad, you break it up into innocent pieces, scramble those, sneak them in, and assemble them where no one's looking. For example, if SCRIPT says "start executing this very bad code", you break it up so it says SCR in one place, and IPT someplace else, and later you stitch them together.
      How do you detect these kinds of attacks? Well, you have to do what the attack wants, actually. You can take a look at the plan, the raw material of the attack, and look for patterns you've seen before. You can look for SCR and IPT, of course, but that doesn't help if someone uses SC and RIPT. You can use heuristics, little handy guidelines that say things like, "if someone is assembling a string, and it is S-C-R-I-P-T letters long, that is suspicious."
      But in the end, you can't figure it out just by looking. This is why Alan Turing is famous, that's the part he added. At some point, to find out what's going to happen, you are just going to have to fire up that machine and see what happens.
      That's how insane the standard environment is.
      I am literally saying that it might be worth it to fire up an entire virtual machine and just see what happens, to see if a string is valid, before handing it off to my little snippet of Drumkit, spinning there in the cloud, all by itself, long after I'm gone.
      This is in addition to the standard environment VM, by the way, that I've already inserted here. The standard environment forks a whole extra universe (or two, or...), just to see what happens.
      Anyway, this is one of the stupidest things I've ever come up with, but it got stuck in my head yesterday, so I just wanted to put it out there.
      I mean, if we're willing to burn processor to mine fucking Bitcoin...
    Keeping that little bottle safe
      (5 min read)
      I didn't spell it out in the previous post, but I think it's an interesting notion, one that I've been mulling, so here's some more context about this sentence:
        This code depends on the standard environment to sanitize data.
      One of the things about keeping old stuff running is that it breaks. Except with software, it doesn't really break, everything around it breaks, and it can't keep up, it wasn't built for that kind of thing. Software has really, really, really specific expectations about how things are. If you think you know someone whose worldview froze the instant they entered high school, and they've never really adjusted to acting like a real adult? Do you know entire swaths of society that can't handle changing demographics and instead try to hang Vice Presidents? That's peanuts to software.
      I have an original model iPad, it's more than ten years old now, and it still works. Except it doesn't, really. It can't be made safe. The code that's in there, particularly things like network access, and dealing with information that comes from networks, is out of date. That means that it's pretty easy to come up with something that can flummox that iPad into giving up stuff it shouldn't, whether that's reporting your credit cards, or mining bitcoin, very, very, very, very slowly, while it shows you ads for casinos.
      You can't get a software update for that iPad, if you enable wifi and ask it to check, it will tell you that its software is up to date. This is, of course, complete and total nonsense. It's not up to date, there just aren't any updates available. It is not in Apple's interest to update the software on that iPad. Buy a new one.
      The traditional way of looking at this problem is, jailbreak your iPad, then you can put whatever you like on it, no matter what Apple thinks you should do with your money. The problem is, this is a really stupid fucking idea, and doesn't actually get you to where you want to go, which is to use the iPad for things it is physically capable of performing. If you jailbreak your iPad, you still have to deal with the fact that people are going to take advantage of that, and you are back where you started: keeping old hardware safe for use, generally by simply disabling Wi-Fi, or designating the device for a single, safe task like playing games.
      In the design I sketched out yesterday, I said that the input was being sanitized by the standard environment. What I mean by that is, the safety of the input is being outsourced. This is not the same as "I use this string handling library and when they find bugs they update so I have the latest". That's at a lower level than I'm talking, and that's the level that is always fucking breaking. I spend literally months thinking about whether or not I should upgrade my IDE to the latest version.
      People think this is easy, software updates itself these days, what is the deal. Well, if your code has to run for decades—like it does everywhere in the real fucking world—then you have to be able to work on it for decades. And tools are always changing, all the time. There is nothing less stable than a set of developer tools. If you have a code base with only 10,000 lines, which is basically nothing once you get really into solving big problems, you have more than 10,000 separate things that can break. And those are the things you can break, all by yourself, without help from someone that decided that /Library should now be hidden, or the new build system really is so much better, or whatever.
      So the idea is that the sanitization happens on the outside. The data is sanitized before it gets to the old, broken, thing. This sounds insane, really, am I saying that Apple should operate a proxy service that sanitizes the entire internet for my old iPad? Why yes, I actually am.
      No, really, you have got to be fucking kidding, are you serious about this? Well, why not? The security issues in my iPad are known, they can be fixed. We know that because they've been fixed in newer iPads. Which sounds, to anybody who knows anything about why that old code can't be trusted, completely insane. Because the reason it can't be updated is that it needs to be fixed. It needs to be rewritten. It was architected with stupid assumptions, and the reason there's a security hole right in that spot is because someone left a bug that allows you to craft a JPEG header that will confuse it, and let you execute the code you stuffed into that header. The way that exploit got fixed was to entirely refactor and rewrite that subsystem, and doing all that work for old hardware is not profitable.
      But, we still know about that exploit. So it's plausible, we could, in theory, sanitize that image, render it safe for use in my old iPad. Let me be clear about just how crazy this notion is: I am not saying Apple should run a proxy service that safeties up that image and fixes every possible security issue in it. (Though, I think that would be a natural side effect.) I am saying that Apple should be running a proxy designed specifically for that iPad, and its known exploits, that can render things safe.
      Like I said, it's an insane idea, just one I've been mulling around, and for the iPad scenario I'm painting, it's pretty unrealistic. But I just wanted to draw attention to the idea that maybe code could be made safer by externalizing some things we normally assume has to be done within that code itself.
      That's what the standard environment did, before the string got to my ancient little snippet, spinning away there in the cloud, long after I'm gone.
      See Vernor Vinge's book A Deepness in the Sky for more about how software ages.
  November 11
    I want a parallel universe time machine that lets me break off chunks of reality for others to play with
      (12 min read)
      Obviously, this already exists, and it is called Minecraft, so I am talking about something other than that.
      I'm working on another post that has a bunch of profanity in it, and a couple other animations, and there are the other literally hundreds of projects I am working on, but I don't want to work on any of that stuff, I need to take a break, and write about simple happy fun stuff.
      I actually have a simple happy fun stuff post in the hopper as well, because I have been having enormous amounts of fun with simple onion-skin animation, and I'd like to write about that. But I want to be extremely careful, because I am pretty sure the app I am using is actually aimed at kids, and I am going to do my best to ensure that anybody who comes by to read that post doesn't have to deal with the rest of my work, which is actually kind of sweary.
      So instead, I'm going to admit that I'm nuts and that, to relax, I like to think about building crazy things, and some of those things might actually be practical, if, say, someone else built it, rather than me possibly one day having the chance to sit down and do it right.
      Here's something I want to build but probably will never get around to, which I really wish someone else would build, because it would be awesome to have around. I have a lot of ideas like this. Writing them all up is a big reason I have the blog part, so here goes—
      Eventually I will get around to doing a real post, or possibly a fractal infinite set of posts, on the Loaf Question, but basically it's the story of how I, well, took apart another man's life's work, poked around inside a machine intended to hold every secret, ever, and, umm, repurposed it for my own devices. Literally.
      Apparently this is something I keep doing, I don't know, something something human.
      Anyway, spoiler—
        Seriously, if you want to go figure it out yourself, stop reading this post Right Now and go see the forum thread, because I present it as a mystery there. It's not too long a read, and in fact one of the original builders of the great machine in question, came by and, well, I have to say, that was literally amazing for me.
        And you will absolutely recognize the machine I'm talking about, and exactly whose life I'm rummaging around in, once it makes its appearance, trust me. This is an amazing piece of human history, and nobody, besides the original madmen, has ever taken it apart and rummaged around the way I did. No joke.
        Suffice to say, the rest of this post is, apparently, once again, about one incredibly amazing life's work, and you get one chance to discover just what the fucking hell I was looking for, and what I found, when I discovered the Snarfs, Turtles, Recipes, Cookbooks and Fossils. Let alone the Ent.
        So go take a look there, and then come back here for another fabulous episode of "Gary Teter rummages through someone else's life's work, and makes a macrame owl that is also a potholder."
      Right, so for me the interesting part of GitHub is actually the git part. It's the storage part, just like a regular file system, but it is versioned.
      Each version is a parallel universe, where things were just a little (or a lot) different.
      And it lets you compare, what is the difference between this universe, and that one.
      Also, the past is just another parallel universe, so you get a time machine, too.
      And if someone makes something, and you want to take that thing and make it yours, you can, in fact, make your own parallel universe. With your own time machine.
      I don't know if GitHub has this, but I am going to say that they also have, or should have, an easy way to spin up one of those parallel universes, to breathe its life into a virtual machine that can execute the code I have put there. This part is basically AWS Lambda, I want as little friction as possible, I want that virtual machine to behave as if it was always there, listening for anytime anyone, anywhere, wants to call it and ask it to do something
      Also, I would like this universe to be operated by someone who has solved the very, very hard problem of keeping my universe EXACTLY THE FUCKING WAY I SET IT UP WITHOUT RANDOMLY CHANGING THE RULES OF THE UNIVERSE ON ME JUST BECAUSE SOME ASSHOLE CHANGED SOMETHING WAY OVER THERE IN THEIR OWN GODDAMN UNIVERSE.
      There is code today running, at my employer, that processes millions of dollars of real money all the time all day long. My paycheck depends on that code, and so do a lot of other people's. Due to some quirks of history and the fact that when you are sailing a ship, you need to actually keep operating that ship while a) going where you need to go, b) repairing the ship, c) adding entire new masts and sails and shit to the ship, and d) replacing the parts that wear out, my paycheck, as well as a lot of others, also depends on a library of code that I wrote more than twenty years ago.
      Obviously, you want to replace the old code, we are in the middle of a long, long process of paring away and refactoring and stripping off pieces and replacing them with modern parts. And it is going well, even though everything is always on fire. But for now, that other code is still in there. And that code has gone through makefiles, jam files, ant files, I don't remember what else, because you know the last time I fixed a bug in that code? Probably a decade ago. I can't remember.
      Code doesn't actually get old, and creaky, and break. All the shit it's hooked up to is what changes, behind its back, when the code isn't looking. If you have code that does a thing, it can keep doing that thing. It's when you need it to do a different thing, or the other things that code is connected to change on it, which is, well, doing a different thing, that's when you need to change the code.
      Here's what I do know about that old code. If I needed to, if we found a bug, I could build it again. I do not mean I could write it again, though I could do that, and have, better, in various forms throughout the years, and we're using some of those parts now, and some of them are now due for replacement. We barely use any of the original code by now, and what's left is on its way out. No, what I mean is, I have all the jars and libraries and whatnot that I need to compile it, one click, from original source all the way to the various packaged installers we used to offer back in the day.
      I think I can actually execute the build files themselves, the ones that build literally everything. Unfortunately, that code needs to run on machines that are twenty years different from what that code originally required and expected, so I dunno if I can actually run that makefile. But, if I had an appropriately configured virtual environment, I could do it there. Really, though, we're down to a handful of jars, and you can do those by hand. But the jars needed to build those jars, all that stuff, I have that in my own parallel universe time machine.
      Which, now that I think about, has gone through rcs, cvs, svn and git.
      I am getting used to the idea that when I build my code, it's an entirely reasonable thing that my build system will go out on the internet and download things to a special little cache that is literally outside the area, under version control, where I stick the fucking jars I need, and I can use my own time machine to root around and figure out what the idiot I was twenty years ago had in mind when I wrote this old, crappy code in the first place.
      What I am saying here is, I have opinions on the importance of the stability of environments and systems that I have spent ridiculous amounts of time and care setting up and suddenly now I'm outside my happy place and need to go back to looting other people's ideas.
      I haven't been keeping up with what Dave is doing with Drummer and Drumkit the past few days regarding GitHub, so I have no idea if he's already spelled out his ideas in this space, and I'm the kind of person that is way too impatient to go see.
      I think what I want, and I'm kind of thinking out loud here, is an outline.
      I am doing an un-outliney thing here, and separating the commentary from the actual example outline, because it's easier for me to see what it should look like when it's as close as possible to the final form, and parts of the outline I'm presenting, are, naturally, meant to be collapsible for their own reasons apart from any context I want to provide.
      It's got a lot of attribute set up behind the scenes, but I want it to read as clearly as possible. So you can think of the below as representing the "rendered" version, similar to how in Drummer a node representing a tweet is presented with a bird icon, indicating there is more information behind the scenes. The bird is an affordance, this is more like a dynamic summary or something, I guess? Maybe a virtuality.
      The "this is an icon" text is the sort of thing that is automatically generated. The "when you click it" is the description I wrote as the provider of the code.
      When you click on the various things, like "revised 22 times", you could pull up the suitcase icon to edit attributes. I guess this thing would probably need a pretty structured editor.
      But as long as I'm making up work I'm not going to do, maybe it navigates to a repository or displays a history inline, or something. I like the history inline thing, now that I think about it for exactly two seconds.
      The part under "here is the code" is exactly what you would put into your icon bar or menu bar opml file in Drummer. In fact, it gets put into your icon bar, because what's in your icon bar is actually a node that points here.
      Here, in fact, is a place in GitHub land. It's a parallel universe you can point to and navigate to, and be assured that when you look for it, there it is, the way you left it.
      The "standard string" part goes to the official definition, which has been carefully thought through, unlike this design. The entire "what it expects", "what it provides" section is automatically generated and cannot be edited. Imagine it was created by the compiler or linker or something. Part of the signing process, perhaps.
      (There should probably be a signing process, somewhere, but I really hate those, they are devised by people who failed to work enough cruelty into setting the clock on a VCR, do not get me started.)
      Often, the input will be opml or JSON, but here it is just a string.
      The "standard environment" takes you to details about, well, the current standard environment. The standard environment is what does things like cleans strings etc. It's a very narrow subset of verbs, just the ones that keep changing but are expected to provide consistent, safe, behavior.
      "Limited HTML" is obviously defined somewhere, basically it's some escape entities and maybe bold tags. The standard environment is extremely good at parsing and escaping. "Limited HTML" could also be, say, Markdown or something else.
      Discovery of these snippets of Drumkit, whatever you want to call them, as well as the obvious gaping security issues to be thought through, are left as an exercise to the reader. Like, maybe there's a big outline, or we all share links or something? I don't know.
      And, I dunno, some way to install these little Drumkit widgets or extensions or plugins or whatever they are, the usual UI stuff.
      I do think maybe, perhaps, I really have not thought this through at all, actually, security issues might get easier to deal with if you can lock down the definition of what you're dealing with, that is, the universe isn't going to change behind your back.
      But, no universe is an island (ha!), and your code will still have to deal with input that may be trying to kill it, or make it do something you never intended. So if an outside universe is sending you information that exploits a bug in yours, you can't really protect against that, can you? It's the record that breaks your player, thank you Madame Tortue. This is a pretty hard problem.
      The minus button that tells you what you have selected
        This is an icon you can add to Drummer's icon bar.
        When you click it, it displays a dialog box with the currently selected text.
      Who made this
        Created by Gary Teter
        First posted Thursday, November 11, 2021
        Revised 22 times
      Here is the code
        minus
          dialog.alert (op.getSelectedText ());
      About the security of this code
        What it expects as input
          This code expects a standard string.
          This code depends on the standard environment to sanitize data.
          The input cannot be treated as Drumkit
        What it provides as output
          This code does not provide any output.
          This code displays an alert dialog box within Drummer.
          The output displayed is interpreted as limited HTML
      OK, so that's the Drummer part, obviously this Drumkit code runs inside Drummer. And it's accessing a node and its properties, so the security description above needs work, it's not just consuming a string.
      But, you know, it doesn't have to run inside your browser or on your machine.
      Maybe your little snippet of Drumkit actually is just waiting there, up in GitHub land, waiting for someone to ask it to do something.
      It wouldn't be displaying a dialog box to show you what you have selected, duh.
      What would that Drumkit code be waiting to do for me, or you, up there in the cloud? It could, say, talk to other things in the cloud, even other bits of Drumkit code, or bits of code that weren't written in Drumkit at all, but know how to handle a standardized remote call.
      I dunno what exactly that code might get up to, but I am very curious to find out.
      Also, that is a seriously huge amount of work I've just described. If you're thinking that Dave, or anybody else, could just up and build that, or that I expect anybody to, or that I have the time to, well, you might be disappointed.
      Of course, if you think you might like to just up and build that, or parts of it, holy crap please get going because I really want to see something like this, in one form or another.
    A partial list of some things I may have actually been wrong about
      (2 min read)
      "Blog" is a real word that will not drive me insane every time I hear it
      Why would people watch other people's home videos
      Why would you use an RSS reader to download giant audio files so you can listen to people talking when you could use an RSS reader to read
      Why would people want to give rides to strangers in their own car in their spare time
      It is completely rational to download the same bytes, over and over, to watch a video more than once
      People would actually take the idea seriously that a fucking computer is capable of safely driving a car in actual traffic with actual human lives right down to fucking school zones with children for fucks sake have you seen them children are literally insane without actual fucking magic being applied
      Why would people want to read Christmas letters and participate in Thanksgiving arguments, with everybody they have ever known, constantly, every day
        OK I admit that wasn't actually my question. But I did get Facebook wrong. Only an actual, no-joking, cartoon supervillain could be responsible for what literally billions of people see, and talk about, and therefore think, and therefore believe, and therefore act on, and yet think so little of the implications of that, and care so little about anything except growth and domination and power, that blame for literally uncountable actual human deaths, and social divides that could cause far more, can be aimed directly, solely, at their individual, specific, personal, neglect and greed. Fuck you, Mark. Think about somebody besides your fucking self for one fucking second. You fucking, fucking asshole.
      Why would people want to be notified about what you had for lunch on their phone
      Daniel Amos will one day receive the recognition they deserve
      Bitcoin is not the stupidest fucking idea ever that we will later discover is actually an information attack from a parallel universe
        I believe the jury is still out on whether it's actually an attack from another kurt, but I just wanted to put that out there. I will write more about this, as I have opinions about performing waste work when not one, but two, towns where I've lived, have been completely destroyed by natural disasters. I hid from the tornado that destroyed Xenia, and Paradise has burned to the ground. This place is far, far more fragile than any of us want to admit, and we're all setting tulip bulbs on fire.
      The America I grew up in, the one that believed in immigration and immunizations and science and taxes and parks and was arcing toward justice, however imperfectly, would be the one I'd live in
      Using technology to enable everyone to talk to everyone else will increase understanding and basic human respect
      Why would anybody want to watch other people play video games
      Dave Winer should adopt "Drumkit" as the name for Drummer's scripting language. HA!! FINALLY GOT ONE!! IN YOUR FACE, UNIVERSE!!!
  November 10
    Things I'm glad Drummer doesn't have
      (9 min read)
      There are a lot of things Drummer has that I am pleased with, and those things will help me build things that I think Drummer should have, but doesn't. And there are many features that I'm sure will show up eventually, whether built-in or provided by someone else, somehow.
      (One of the things I'm interested in regarding scripting and GitHub is that particular aspect: Why can't I just break off a chunk of code, and let other people use it?)
      There are a lot of things I am glad that Drummer doesn't have, and I'll enumerate them all someday. Here's one: No fucking metrics.
      (Technically, this is a non-feature of Old School and not Drummer, but for me they're the same at the moment.)
      I am aware of what metrics get you, in ways that only someone would know in their bones, whose ability to eat food purchased with actual dollars instead of a benefits card depended on their ability to determine precisely who their customers are and what they want.
      The panopticon peers deeply, and you leave so much more information about what you are looking at and doing than you have any idea, and everyone around you is taking advantage of it, all the time, constantly, right now, this very minute.
      A quick example, a true story, from twenty years ago:
      The phone rings. We check caller ID. We look in Roundup, my version of the panopticon.
      Roundup has every email any employee has ever exchanged with a customer, ever. That's not your email inbox, because you work for me. When you quit, I need to know everything you ever promised the customer, because that relationship belongs to me. (You also have your own relationship with the customer, and if you want to go start your own company and poach them, it's my own fucking fault for making that situation desirable for anybody concerned. I'm not a vortex.)
      So when you email us, we can instantly find out, have we talked to you before, and what have we said, if anything. Now, that's a little oppressive, I guess, but once everybody on the team is aware that's how email gets handled, it works out OK. In fact, customers like that part because it means anybody they talk to at the company can at least look into helping them, even if their usual rep is out. No internal silos.
      Here's where it starts to get nuts.
      We also run our own website, so we get metrics. Now, these are the kind of metrics I want, so I could give a shit about total numbers. I do not care one fucking bit if ten thousand people looked at that page. In this instance, there is exactly one metric I want:
      What are you looking at?
      So I can I see, by IP address, everything on our website you looked at. I can see what links you clicked on, and I can see what pages you looked at. I can see if you came back and looked again. I can see what features you might be interested in based on what you are looking at.
      Think about that. I can read your fucking mind. I don't know who you are yet, but I can see what you're looking at.
      Now, the product we were selling at the time was aimed at a pretty small group of people. Most markets are like that, you may want everybody in the world to buy your awesome developer framework, but, reality: people do different things. Only some people care about this stuff, so there are small discussion lists for sharing ideas and code snippets and asking questions. This was 20 years ago, so everything like that was fragmented into little communities rather than just being on Stack Overflow. And this discussion would happen over email.
      Email gets delivered to your IP address. And it gets sent from your IP address. And email has headers. And all this can be stored in a database like Roundup. Just like our web server logs. Which means Roundup can make a direct connection between your anonymous website visiting and your identity and interests.
      So, when we checked Roundup, there was a very good chance that not only do we hope you are a potential customer, hello random caller, it turns out we could also find out, literally instantly:
        Your name
        Where you work
        Are you posting from an edu or com address, is this your job or are you a hobbyist
        Are you a consultant we might sell to repeatedly, or is this just a one-off interest for you
        Have you specifically looked at any page on our site
        Which features are you interested in, based on what you're looking at
        What problems are you trying to solve, based on your participation in the discussion groups
      In fact, we often knew why someone was calling. Someone we'd never talked to before. Think of that.
      We could get all this just from caller ID.
      At the time, caller ID was just digits, not the name. But people include phone numbers in the footer of their email. And Roundup indexed literally everything. So we could type in the digits we saw on the caller ID and know all this before we even picked up the phone.
      It should be pretty obvious how useful this is to have at the literal tip of your fingers. It's creepy as fucking hell, of course, and we had to be careful when talking to people for the first time, because, well, it's creepy as fucking hell. You've never talked to us and we have a literal file on you already, organized by interests, constructed instantly, based on just normal stuff you were doing, living your life.
      Also, there is jack shit you can do about any of it, because you voluntarily provided every single bit of this information. Perhaps without being informed, without real consent, but it was yours to give and it was ours to ingest and turn into money in any way we could.
      Note that none of this depended on Google, or cookies, or URL shorteners, or geotagging, or Facebook, or facial recognition, or cell tower pings, or anything else fancy. We knew your email, because you'd sent it to us, albeit indirectly. Everything we knew, you told us.
      We didn't spam you. We didn't sell your name or personal information. We didn't even buy your personal information. You never knew, and, in fact, if you never called us, we never knew, either. What on earth could we possibly want to do with the information we gathered, besides what we did, which was provide excellent customer service?
      This is, by the way, the justification the NSA uses for keeping our network traffic around in databases, because it's not really a panopticon until you go look up someone's caller ID, right?
      We used an email client, our own Apache logs, and caller ID. (And Roundup, of course.)
      There is a me-shaped hole in Facebook that defines me as precisely as if I had a Facebook account or I was on Mark Zuckerberg's personal "let this guy on the space ark" list.
        (Fuck you, Mark. Think about literally any single human besides yourself for one fucking second. You fucking asshole.)
      So I know the value of metrics.
      But sabotaging the panopticon is not the only reason why I'm glad Drummer doesn't have metrics. I'm glad because I cannot possibly find out if anybody is reading this. And that is turning out to be amazing.
      You can't turn off those little hearts on Twitter. There is no way to interact with Twitter in any meaningful way that does not immediately jam it right in your face just how funny or smart or clever you really are or aren't.
      This is useful, and really the only thing Twitter is for. It is literally Twitter's reason for being, so it's no surprise that if you look in the settings menus, you will find several pages that look like they might be the key—appearance, display, etc.—there is no option to turn this off. You can't know what's popular unless you know what everybody else is looking at. And that everybody else is looking at it.
      There is zero point to Twitter if all you can do is say things and make things and let people see them and read them and then say things and make their own things and then you say things and make things and let people see them and read them. There is absolutely zero value in human interaction that can't be measured and ranked. It is absolutely critical that you be able to see, immediately, how popular an idea is, and how many people listen to whoever said it.
      Which, fuck that.
      So I'm glad Drummer doesn't have that particular feature. I can't tell if anyone's already read it, so I can fix mistakes. It doesn't have to be absolutely perfect. I can make mistakes. I can read it and decide for myself that it sucks. I can apply my own judgement.
      I can do all these things by myself, but what happens is, in my experience, that I just never end up finishing anything, because it's not perfect. You have no idea how many things I want to fix about the way the blog part looks and reads. But I've decided that I no longer give a fucking shit. I cannot keep waiting until I finally get it right. I have too many ideas to polish each one before putting it out there.
      As I type that, it sounds completely insane. Just preview before publishing. How hard is that? I have no idea why it is hard. But I do know that you can hit that preview button for literally decades, and never hit publish.
      Which means the other feature I'm glad Drummer doesn't have, and this is one I could easily add myself—what I am referring to here is mostly an artifact of how I am approaching Drummer— is preview.
      There is something here, something about the fact that it is public, but I can still fix it, that is liberating to me. I can fix a typo. I can reword a sentence. I can clarify and polish.
      But first, I have to hit that cloud up-arrow button.
      I drive a stake in the ground and say to myself, OK, if you want to see how this reads, formatted and in context, the way the public is going to see it, bucko, you are going to have to publish it.
      If you think you are done, then publish it. If it says what you want to say, then publish it. If you've done your first couple passes, and it's time to just sit back and read for commas and typos? PUBLISH IT.
      You want a preview button? Your preview button is NO PREVIEW. FUCK YOU. MAKE SOMETHING.
      And the fact that it's easy to add new posts, in fact, you have to write new posts, that's how blogs even work, means I can go back and revisit a topic and write something new if I think I find more to say, later. I don't have to get it all absolutely fucking right the first time. I can iterate. This post covers ground I trod in the very second post I put here in the blog part. I'm making a wagon rut.
      I'll never get it right. That is literally impossible. But I can keep beating on that drum.
  November 8
    We're going to keep doing this until we get it right
      (16 min read)
      I'm going to reach deep into someone else's life's work, and grab hold of something they feel passionately about. I'm going to take that thing and appropriate it. I'm going to say, thank you for suggesting this, and I am almost certainly going to misunderstand what you actually intended, but I'm going to take your idea and use it for my own purposes. I did this recently, and I regret the way I did it.
      But I'm going to do it again. Why would I do that?
      Here's the idea: The empire never ended.
      You thought I was going to say something about Drummer, JavaScript, GitHub and DOS, didn't you? Well, I'll get to that particular yoink in a few minutes.
      But first, I need to badly misstate something Philip K. Dick broke his brain trying to comprehend and explain. This is a man who wrote many, many novels that could be described as pulp science fiction attempts to explain just what the fuck reality actually is. They've since been made into movies like Blade Runner and Total Recall and a dozen other blockbusters, but he barely knew that was going to happen. Mostly, he wrote and wrote and wrote.
      He also took a lot of drugs, and, in particular, his work A Scanner Darkly explores what that sort of thing can do to your brain if you keep it up. It's possible this caused his divine revelations, but maybe god really was speaking to him through an ancient satellite, and that burst of pink light that shot from a girl's necklace and changed him forever was a real thing. It's hard to say, none of us were there. And all we really have to go on is what he wrote about the experience.
      He wrote a lot about this, in fact, thousands of pages, called "the exegesis," in non-fiction form, and lots of novels like Valis. But it really doesn't matter. There's no way you or I or anyone else could possibly understand it the way he did. And that's the kind of irony that hunts you down, because his entire fucking life was explaining this one remarkable revelation. And we'll never, ever get it.
      All we really can do with anybody else's work is dig around in it and see if we can find anything useful. Your life's work is a junk drawer to the rest of us. That's OK, you'll be dead, and you will have no idea that billionaires trade your paintings for hundreds of millions of dollars instead of doing something useful with their money. Probably better to be dead in that case anyway, especially since the odds are that you, like 99 percent of humanity before you, died poor, and sick, and hurting. This is the way of my people, and yours, too.
      So I am going to reach into a man's life's work, and I am going to pull out one little idea and run with it. If you have the slightest interest in science fiction, the nature of reality, how to tell a story with plain language without being Hemingway, retelling a story again and again trying to finally get it right, well, you should go look at his stuff. Real writers are pretty impressive once they get their teeth into something, and Phil Dick chomped deep and hard.
      (In particular, I recommend thinking about what he meant by the idea which I'm about turn into a lamp that is also an ashtray.)
      The empire never ended.
      The Roman Empire never ended.
      The Roman Empire is here, right now, today.
      I mean, look around, there are centurions and robes and senators and slaves everywhere, right? Obviously not. But we still have the military, and fashion, and government, and forced labor, right? Sure. But that's facile, and I don't think that's exactly what Phil Dick meant. But again, I also can't really care what he meant.
      When I sit down and start typing here, I have no idea what I'm going to write about. That's deliberate. I spend a lot of time thinking, and less time typing, but I still generally don't know what I'm going to do with the raw material I'm mulling over. Usually, I don't even know I'm going to write something. (How this post happened: I was trying to sleep, I got up, I typed, I hit the cloud up-arrow button, I went back to bed.)
      Here, for example, I was fully intending to run with the notion I've described as facile. It's a useful way to look at things, actually: There are human needs so common, so natural, that structures inevitably arise, and we should look for similarities between the solutions of the present with the past with the possibilities of the future. Which, duh.
      So instead, let's take that "Roman Empire never ended" thing and get all Connections with it. This is a series of science shows from the '70s where James Burke picks some event or invention from the past, and explores all the little ways the future got created from that, in ways nobody could possibly have predicted at the time, when nobody was actually looking.
      In this case, let's talk about wagon ruts and railroads.
      Back before the internet was the internet, back before anybody knew what dot coms were or mined bitcoin or posted selfies, there was Usenet. And dialup bulletin boards, which were exactly like Facebook, except slower. This is where we all first discovered just how fast folklore can accumulate. Prior to this, folklore passed via word of mouth, and samizdat, and fax, and I guess there were things like books, too, but books are slow. These other things were faster, so that's how folklore develops.
      Folklore is stories we tell ourselves about how things are. Forgive me for being stupidly obvious. But we like these stories, we need these stories. They help us make sense of things. They help root us in a shared experience. When you are a kid, and you learn that pop rocks will make your head literally explode if you drink a coke, now you are in a shared, consensus reality with everybody else aware of these simple, scientific facts.
      I'm trying to change your reality, right now, by the way. (Too late! I already did.)
      The best folklore, the stuff that sticks around, is the stuff that speaks to people. It has plausible explanations for complex phenomena. Or it tells colorful stories about colorful people to make a point that resonates with people, one that reinforces beliefs we find useful, or comforting, like the value of hard work, or the lone genius, or the foolish wise. Of course, if the story does all these things at once, you will never stop hearing people talking about the Bible.
      So I have no idea if the wagon ruts-to-railroad gauge story is real, I'm sure it's been investigated and debunked, or validated, or set aside and later reconsidered, or held up as an example of something kind of true but which elides important historical facts and therefore deserves an extensive talk page on Wikipedia.
      Here's the gist:
      If you put wheels on your wagon, and then drive that wagon around, you will leave ruts in the road.
      Other people want to use the same road, so their wheels end up fitting the same ruts.
      Later, when it's time to invent railroads, you need parts, and those parts get delivered on roads established millennia ago by those wagons. Also, you make your railroad tracks that same width because it really ties the room together.
      Millennia ago, the Romans standardized their wagon wheels, and this allowed them to take over the entire world, because all their wheels were interchangeable. Just like their horses and elephants. And now, our wheels are all interchangeable, too, every couch and bed and every single car is exactly the same width, and they drive in the same ruts, and the trains, apart from exploding occasionally, fit precisely in your living room just like in Julius Caesar's day.
      This is why your typewriter says QWERTY on top. If you put your wagon wheels too close together, they will jam, so you deliberately make them harder to use. Or something. It's hard, with folklore. Things drift.
      So, the empire never ended.
      And you see, if we could just do that, but with technology, instead of, umm, wheel technology, then everything will really start to flourish!
      That's what I'm saying, right? This is where you go when you write this essay. There's a checklist. You have to name-check mass production and Henry Ford, of course. Bonus points if you can work in an aside about how ironic it is that behaving like soulless automatons gave us the free time to maximize our potential to sit down and watch some quality TV. Slip some Muybridge in there, too, and some Warhol soup paintings while you're at it.
      OK, that's not this post, which apparently isn't even about standards at all.
      I'm done with the Roman thing, by the way. If you're looking for a resolution to that notion, a point that draws it together, something that explains just how this essay's version of the story is different from and more useful than Phil Dick's, you're not going to get it. Sorry, that's the way it is. I reached into someone's life's work, and I appropriated, and I misrepresented, and I was shameless about it. I'd do it again. I probably will. (I absolutely will.)
      Because that's how we do things around here, we humans.
      Every single word of the preceding, every bit of it, is to prevent criticism of the following. Because I'm about to take someone else's life's work, this time in the form of a deceptively simple comment, and run with it in ways that are absolutely not anything they said.
      If you want to read just the GitHub and MS-DOS parts, you could skip all the previous stuff and start here. Probably should've mentioned that up top. Plus, it’s incredibly late and that first part, in particular, needs some editing. (“Some,” he says.)
      Here's what Dave Winer actually said:
        GitHub could be the next MS-DOS.
      It's a good choice. You could go with the Apple II, or HyperCard, or Windows, or even Facebook. But MS-DOS is good, let's go with that.
      If you pick the Apple II, you're saying, this is the dawn of the era in which we all finally get to taste the power of computing for ourselves. You don't have to rent time on a mainframe, you don't have to solder it together yourself and flip switches, you can finally do it yourself. You can shade this in various directions by selecting other machines from the same era.
      In particular, the Commodore 64 pushed this so far it killed the company—it gave everyone a chance to use a computer in ways that the Apple II, or even cheaper machines like the VIC-20, didn't. It hit the sweet spot, and left a mark. But the Apple is the one you'd pick these days, because people, improbably, still know who Apple is.
      If you pick HyperCard, bless you, and I'll be over here writing up some important notes on my Newton. HyperCard says, this is the first time you can make a computer do something, by yourself, that isn't 10 PRINT "RADIO SHACK SUCKS" GOTO 10.
      You can pick VisiCalc if you like, but VisiCalc was never fun. This is not my essay about about how if you just add one tiny little fucking feature to HyperCard, the ability to request a stack over a network, and also have a time machine, humanity could have jumpstarted the last 20 years of progress 20 years ahead of time, but I should totally write that one someday.
      Windows is obvious, blech.
      Facebook is interesting, because what that says is you are going to play for the "progress is social and increasing connections between potential sources of information can only be good for society, because that's just like science" card, and believe me, I want to read a post about how Facebook can actually be a model for advancing justice and scientific truth. I think we all would, right now. (Fuck you, Mark. Stop thinking of yourself for one fucking second, you fucking asshole.)
      So let's look at MS-DOS. We'll set aside all the obvious gags about IRQ and low res and everything we all hated about it back when we had to use it.
      Remember that, how we all had to use it? Why was that? Well, when you choose MS-DOS as your metaphor, you're saying, this is the first time your code can run on a whole LOT of different hardware. There were little nudges in that direction before. For example, CP/M, which was basically DOS, but a couple years early. Minicomputers started out by implementing mainframe instruction sets, which meant your computer could run software written for an entirely different kind of machine. (And from a different manufacturer, which was the real point.). Then there were things like the UCSD Pascal system, which was a virtual machine. This is a computer that doesn't even exist, which is a remarkably useful notion. But computers didn't get fast enough to make this really widespread until long after the MS-DOS era.
      MS-DOS is the first platform worth targeting. The first actual platform.
      Before then, you wrote your code for a platform like the Apple II, and then you wrote it again for every single other type of machine your customers might own. In today's terms, that is not much of a platform, just one type of machine, from one manufacturer. In fact, it's such a dingbat idea that you'd need to go to Kickstarter to find anybody willing to give you money to try it. If you want to really reach people, you go where the people are, and these days, thanks to the internet, that's everywhere.
      MS-DOS was the first taste we all had of that particular dynamic. And it was good. I mean, really good. There was a shit ton of innovation going on. You had to, the hardware was moving so incredibly fast. The idea that you could buy a computer, and use it, unchanged, unupgraded, untweaked, for literally years, and nobody would think twice about it, would have boggled us then.
      Memory standards were going bananas. You could have 640K, then it was extended, or expanded, and there was literally a difference between those two things, but then it became something else after that. Video cards went from proprietary black-and-white to multiple colors at scan rates and resolutions that just kept going up, and up. Sound cards. Joysticks. Mice. Multifunction cards. Clock batteries. Clock batteries!
      And through it all, even though you had to keep rewriting your code to be terminate-and-stay resident, or take advantage of what you could do on a 286 or 386, or use undocumented API calls, or draw your own windowing system with character-mode graphics, just to keep up with the relentless pace of change and explosive innovation, there was one thing, at least, that didn't change: at least it was still DOS.
      And that fueled the innovation which fueled the change which fueled the innovation which fueled, which, well, you can see where I'm going with that.
      But why GitHub? I'll tell you why, because Amazon blew it, just like TiVo, and I'll never get why, but that's just because I wasn't in the room when things got voted down for whatever reasons.
      First, let's do TiVo, because that one really pissed me off. Way back in the long ago, we had only three channels on the TV, and it sucked in ways you cannot believe unless you were there. You couldn't pause it, and you couldn't pick what you wanted to watch. Whatever was on, was on.
      VCRs changed that—you could rent a movie, which meant you could choose when to watch it, and you could pause it whenever you wanted. This was a great advance.
      Seriously, this experience was so incredibly fucking awesome that Hollywood threw shit fits because they thought we'd all just sit at home, remote in hand, clicking endlessly through choices, watching hour after hour after hour, and never once go to the theater. This obviously never happened.
      Anyway, it worked pretty good for movies, but for actual TV the VCR was a complete fucking disaster. It was so bad, entire swaths of the economy were devoted to writing and performing jokes about setting the clock on the VCR. It absolutely eclipsed the airline food sector, destroyed rolling up the toothpaste tube, and came close to unseating relentless, horrific sexual harassment, like that featured during the Henry Blake era of M*A*S*H, as the top source of quality jokes.
      TiVo changed that, like the iPhone changed cell phones. Before the iPhone, I wanted Apple to make a phone. I had no idea what kind of phone they should make, but I wanted them to make one, because my theory was, maybe I wouldn't want to fucking jam the phone right through my temple in frustration every time I used it, because maybe they'd spend some time on usability instead of licensing fucking ringtones.
      With TiVo, you could suddenly pause the show you were watching, no matter what show. And you could record shows, without setting the blinking clock, and remembering to put a tape in. And you could watch the show, whenever you wanted. And you could pick which show from the couch, instead of digging through the bin of tapes, trying to remember which unlabeled tape was wound the correct amount through to be the one you were looking for.
      TiVo was fucking amazing. It was so amazing that anybody that had any interest in TV, and disposable income, had one. And those were exactly the same kind of people who might, say, get interested in streaming video.
      TiVo should have owned that shit. TiVo should have completely fucking dominated. There should have been absolutely no room left for Roku to maneuver. Their hardware was already in your house.
      I had a TiVo that could play streaming video. But the interface made me want to jam the TiVo remote right through my temple, which would have been hard, because the TiVo remote was literally delightful to hold in your hand, and curvy and textured and balanced and smooth. You could use it in the dark. You could immediately tell without looking at it if you were holding it the right way. It had a button that would jump ahead 30 seconds at a time.
      I don't know what happened. At the time, I pointed at their software, and decisions to start over and build the wrong thing, from scratch, rather than iterate over what they already had. But that's the software developer in me, and now I know it's more complicated than that. There's egos involved, too. (I am just guessing here. But there are always egos.)
      Anyway, back to GitHub and Amazon. I think Amazon should have owned the spot where I am going to say this is going (and putting so, so many words into Dave's mouth).
      Here's why: Prime, and AWS.
        Prime, because this is where you add value.
        AWS, because you were building this fucking thing anyway.
      I think the notion that Amazon should add useful things to Prime is pretty obvious, so I won't belabor that one. And everyone knows why AWS exists, which is that if you want to scale, you need to disintermediate, and that includes yourself. So you take that monolithic, million-line website templating horror, and you refactor, and refactor, and refactor, relentlessly, until you've split it apart into the dozens of individual services that you can scale properly.
      And then, once you've built it, rent it out to businesses, and make extra money.
      The part that I have never figured out is, why not rent it to regular people, too?
        Why is it so incredibly fucking hard, basically impossible, for me as a normal consumer to take advantage of AWS in any meaningful way? (If you say that I am, every time I watch Netflix, I will punch you.)
        Why can't I one-click a domain name?
        Why can't I just drag some pictures into S3?
        Why can't I have my own website on AWS through Amazon?
        Why does everything have to be free with fucking ads pasted all over that shit?
        Why can't I pay for my website as part of the normal annual Prime tax I'm paying anyway?
        Why am I limited to talking about simply hosting a website on AWS, anyway? There are some ridiculously cool things going on in the cloud these days. Why can't I put little chunks of code in the cloud and link them together? Why do I have to understand Stack Overflow to make anything work? Whatever the fuck happened to HyperCard?
      The really funny part about this blog post, to me, is that I still haven't even gotten to what I think you could even do with GitHub and Drummer. (I do have some ideas on that.)
      But I hope it's clear that there's an opportunity here, room for creativity to maneuver. And who knows what kind of shit we could all get up to?
      Time to click the cloud-up arrow button...
  November 7

    A heavy-handed parable about finding and fixing bugs
    If you can’t get it to fail on purpose, you cannot possibly know for sure if you fixed it.

      (4 min read)
      An executive uses their executive key to unlock the executive washroom and do executive things. They flush. Sewage sprays everywhere.
      They put out a call for help. "Maintenance! The bathroom is broken!"
      Maintenance, of course, has no idea what the problem is. It could be anything. There's lots of parts to a bathroom that could break. Maybe the lights are out, or something. Last time, it was the soap dispenser.
      Because they've seen this sort of thing before—executives smelling like shit, yelling about things, this happens more often than executives would rather admit—maintenance knows enough to ask: "What is broken?"
      The executive, quickly realizing that maintenance has not already fixed the problem, clarifies. "There is SHIT EVERYWHERE. You have got to FIX IT. What is wrong with you people?"
      Maintenance is a little nonplussed, but at least this is something they can work with. Could be a burst pipe. Could be a toilet. There was that elk thing last year. "Can you tell us what happened?"
      This executive is extremely helpful, and provides a clear set of steps to reproduce the problem: "I FLUSHED THE TOILET AND NOW THERE IS SHIT EVERYWHERE."
      Aha! Now maintenance can go fix the problem, because they know what's wrong. They have repro steps. And repro steps are fucking magic.
      If you have repro steps, you can prove that you have fixed the problem. And then, you can go home and do fun things that aren't work. Because repro steps allow anybody, even an executive, to verify that something is fixed. All you have to do is follow the steps. It is the closest thing you will find in life to an actual guarantee.
      This is literally what science is. That's how magic I am talking: Repro steps are literal science magic. This is how things stay up in the air when we want them to. This is how your light switch works. This is how vaccines get made.
      Here is the problem, written up in repro steps:
        Steps to reproduce
          Flush toilet
        What happens
          Shit goes everywhere
        What should happen
          Shit does not go everywhere
      Maintenance gets to the executive washroom, and uses the maintenance key, which is actually better than the executive key, but they don't say that because it's not good for your career to point out, well, literally anything that might make an executive the least bit uncomfortable.
      So they go up to the toilet, and they disassemble it, and do whatever toilet-fixing thing I'm going to hand-wave away here. But whatever it is, when they're done, that toilet is guaranteed to work perfectly.
      How do we know that? Because we have a clear set of steps to reproduce the problem: Flush the toilet, and if shit doesn't go everywhere, it's fixed!
      Maintenance flushes the toilet, shit doesn't go everywhere. It's fixed!
      The executive is duly informed, accompanied by profuse apologies and whatever other genuflecting this particular executive requires to maintain their executive decision-making powers. Maintenance does not care about the ritual abasement and propitiation because they know for a fact they have fixed this. They go home and do fun things.
      Later, the executive uses their executive key to unlock the executive washroom and do executive things. They flush. Sewage sprays everywhere.
      What just happened?
      In this little parable, that toilet was absolutely working. We know for a fact that toilet works properly, because maintenance knew what to look for.
      With prodding, maintenance was able to extract from the executive a clearly stated set of steps that allow anyone to determine precisely if the toilet is working. Even an executive could verify that toilet was working to spec.
      This was literally the test being applied by the executive when the shit went everywhere, again. This is a failure mode which has been known to directly affect your ability to do fun things at home without worrying how you will pay your kid's doctor.
      There is no doubt about the correct behavior. And that toilet flushed absolutely fine. No shit anywhere. So what the fuck just happened?
      Well, see, there are two toilets in that executive washroom.
      Maintenance verified it was fixed. What maintenance didn’t do was verify it was broken.
      And now an executive got covered in shit, which is literally the worst possible thing that can happen. That is the truest statement in this entire little parable, but the next two are the ones that will keep your family living indoors:
      First, reproduce the problem. If you can’t get it to fail on purpose, you cannot possibly know for sure if you fixed it.
      Second, get a union. Just because an executive gets covered in shit doesn't mean you have to be the one to pay for it, every single fucking time. Sometimes, it's their own goddamn fault. There was that elk thing last year....
  November 6
    What is with the fucking swearing
      (9 min read)
      Eventually, your mom will find the blog part, and then text you, and say mom things like "you are awesome" and "I am so proud". She will also include a bit asking why you feel the need to use the F word all the time.
      This happens to everyone. It's like dreaming about that moped when you're a teenager, because it's a Real Motorized Vehicle you can drive on the street. That means mobile. And being mobile means you can escape the house and go places. You can go anywhere. This is what will solve all your social problems, each of which stem solely from the single fact that you need rides everywhere, and if you fix that one thing then everything else falls into place and you can get to be like everyone else. And you are not old enough for a learner's permit. That is far, far in the future. But soon you will be old enough for a moped.
      You never do get the moped, of course, because mopeds suck, and you're a teenager, which means even though summer lasts exactly three million years, the day you were born the captain said "PUNCH IT" and the stars turned into lines and then you're thrown back into your seat and the car is lurching and shuddering and the tires are screeching because what even is a clutch and are you really supposed to throw your hat in the air like that I think we need to return these and your friends get married and we all move away and it seems so slow and we drift and nothing is really happening and you're collecting a paycheck and paying rent and suddenly we all still feel 21 even though things hurt now and our friends are starting to be dead instead of someone you can just fucking talk to for one last goddamn second.
        Also, nobody even knows what a moped is anymore because anybody with any sense at all is riding a wheel. (Try it sometime!)
        Update: See this post for more about why the wheel is fucking awesome.
      The profanity thing has been on my mind recently, anyway, though, because my kid's around my writing. He doesn't know or care what it says (ask me how I know). But he knows sometimes I have Siri read it aloud to me, and sometimes I go into the other room for that. And I have used profanity in front of him, twice. Which means I remember it twice, and he probably has, with laser-like kid vision memory, noted approximately four hundred thousand other incidences I've since forgotten, or left a cartoon out, or didn't realize he could hear, or whatever. (How have you accidentally screwed up your kid today?)
        Siri does pretty good with profanity these days. But the single greatest Siri- and profanity-related improvement in my life has been this one weird trick:
          Settings / Accessibility / Spoken Content / Pronunciations
          Click plus sign
          Phrase: Trump
          Substitution: FUCK head
          Languages: All
          Ignore case: On
          Apply to all apps: On
          (The capitalization on the substitution helps Siri provide the right emphasis.)
        So I guess that's two reasons why I don't let the kiddo listen to Siri read me things.
        The only way I've figured out how to get Siri to read me the text of most web pages is this weird two-finger downward swipe from the top of the phone, and I can only do the swipe properly half the time. Eventually, I get the swipe correct and Siri starts reading aloud. Try reader mode, too, if Siri starts reading a bunch of ads or menu options. Here's how to enable the two-finger swipe:
          Settings / Accessibility / Spoken Content
          Speak Screen: On
        I made a video so you can see how it works.
      Anyway, the language I'm using is really fucking unprofessional. And unnecessary. I can express myself without profanity just fine. So why would I do it here? It's a tough choice. And obviously deliberate.
      Right off the bat, it's a way of establishing linguistic dominance over a space. This is my fucking space. These are my fucking opinions.
      Nobody is fucking paying me to say this shit because nobody fucking pays you to swear.
      You get paid to write clear, concise text, focusing on precisely what must be conveyed, nothing else. You remove unnecessary words.
        Edit: I removed three words from that sentence just now. Life goes better if you try to remove half the words from everything you write. (And don't send 80 percent of the emails, either. But first, cut half the words before not hitting send.)
      You also get paid to establish a linguistic space, carve it out, and say, "This space is safe. It has been cultivated. It has been plowed under and fertilized and cared for and gardened and it is productive and will not hurt you."
      Does that sound oppressive and corporate and boring and safe and staid and likely committee-approved? Yes! And it's a good thing that we have language like that. Because, It turns out, this is what basic human respect sounds like. No, really. Basic human respect means, over time, people yell loud enough and eventually we all get it into our collective fucking heads that goddamnit maybe we really should listen for once. And then actually do things in the real world that matter.
      Bit by agonizing bit, that clean, corporate-sounding, extremely safe language, converges toward basic human respect. Even if the people who are signing off are doing it because they just want to shut the fucking whiners up and they couldn't really give a fucking shit about wheelchairs or trans people or race or anything else, they are still doing good every time they give in, and the universe becomes just that teensiest little bit better.
      I have spent a very long time believing that nothing I say matters. The fucking Trump administration didn't help with that shit one bit. It's obvious to me that for some people, words are just sounds they make with their mouths. But I've also been doing a lot of thinking, and I've come to believe that real change is possible. I've never been able to create it in the ways I want—there's a whole lot of not even trying in that phrase—but I think I've seen society change in ways that show saying stuff can make a difference.
      So, here I am, saying stuff. And using language I wouldn't show my own mother, or kid.
      I could establish the linguistic space another way. Part of building community is interacting with people in an open, engaging fashion. You use friendly language, kind of informal, and you include some safe personal details, the kind that humanize what you're saying and the image you're presenting. You'll use words like kiddo, and mom. Maybe you'll talk about your dog, or your hobbies. This is good, too. You can see, I'm doing it here in the blog part.
      I've done it professionally, before, too. It's a kind of performance, like anything else we do in public, like wearing clothes. It's a way of creating a bond with your audience, of saying we're both here in this together, and I'm like you. It sounds trite but it really is a good thing.
      These tiny little bits of "hey I'm like you" are what bind us together as living creatures. There is no such thing as just one human. Every single effort made by anybody, anywhere, to understand what it's like to be some other person, is a great good for everyone, and should be encouraged at every single opportunity.
      So in fact, we can see, I'm already using techniques that are designed specifically to draw people together. Why would I use language that will necessarily drive some people away?
      When I was a kid, I couldn't even look at bad words. I couldn't hear them, I couldn't think about them. They were too bad. So I know what that's like, it can cause actual distress for some people to read profanity, no joke.
      Well, part of it is, I can't please everyone. This sounds completely fucking obvious, and it is in fact so completely fucking obvious that it has escaped me my entire life. You can work yourself into an absolute paralysis, if you're a particular kind of person, trying to do the Right Thing Every Fucking Time. (I have trouble writing fiction because I can't stand to see my characters in distress.)
      So the profanity is part of a series of choices to establish some operating parameters—to literally narrow my creative options.
      I've previously written about cutting down on choices, eliminating options, as a way to stay focused on what matters, so you don't bother maintaining things you don't really need. But removing choices also means you're carving out a space. You're walling off entire areas and saying, "I'm not even going over there."
      This sounds bad! Creativity needs options, right? Well, no. Creativity doesn't need options. Creativity will do just fine without options. Creativity makes its own options.
      What creativity needs is problems to solve.
      If you sit there in front of a canvas, or typewriter, or any other creative tool, kitted out any way you like, with the right tea and music and light and whatever else you need, what do you get? That's right, you get jack fucking shit. Because you're just sitting there looking at a bunch of tools with nothing to make.
      At the very lowest level, the most basic thing you need to say is,"this thing I am making is this, and not that." Maybe all you did was just pick a color at random and splash a big red mark on the canvas. Right there, you've just eliminated a whole giant swath of options. But now you have a problem to solve, and creativity now has a little room to play.
      So, when I add profanity to the mix, I remove other options. And that means, either I just kind of mess around and sometimes swear to be edgy. Or, I lean in. And try to do my absolute best to work with profanity like any other tool.
      There are other reasons, like establishing a base set of expectations, a useful way to express strong opinions, a lazy way to express strong opinions, the fact that there are some things about the way that human societies work that just absolutely fucking infuriate me, and all the other usual reasons why people swear.
      But really, I'm swearing here for the same reason other people play games. I can't play games anymore, I can't solve puzzles. They're artificial, some jackass just tried to make it hard, yay you figured out something that someone deliberately tried to make hard.
      I actually love the idea of puzzles and mysteries and hand-crafted wonder, and I love things that are hard for that reason. I love the books that require decoding to find actual buried treasure. I love the idea. But I have no interest in solving those puzzles myself.
      Real fucking puzzles, like how do I get people to take me seriously when I use language that sounds like I'm 11 and just learned my head won't literally explode if I say the word "shit"? Sign me up.
  November 4
    Some things about JavaScript
      (3 min read)
      Instead of sending the boring work email I've been drafting for the past few hours, I'm going to rant about programming languages because I like it here and apparently I have opinions. I guarantee none of them are new insights but I'll get to try describing them myself. In addition, it's been years since I wrote a bunch of browser and server JavaScript, so all my opinions are based on out of date information and therefore completely worthless.
      First, though, I want to clarify something because I want zero confusion about this: I'm kind of sorry now that I've been calling Dave Winer's scripting language Drumkit.
      First, Dave has not contacted me about this. (Nobody else has, either.) Second, it's incredibly arrogant of me to sit here calling Drummer's scripting language by a name I picked, and I really, really hope it is clear that Dave did not choose the name I've been using, and when he picks a name, I will use that name. I just couldn't keep calling it "drummerscript or whatever".
        (I really do like the name "Drumkit", though.)
        Update: Dave likes it, too. Yay!
      It's JavaScript, right? Well, sure OK. But JavaScript comes with some baggage. When you look at most JavaScript code, it looks rational. It looks readable. But what you can do with JavaScript is a complete fucking nightmare of possibilities.
      You think I'm talking about how like everything is always a fucking DOM tree with a goddamn window document model. Well, yes, that shit is fucked up.
      Most programming languages come with a standard library. JavaScript has no standard library, but it does let you organize your code any fucking way you want. And everybody does. That makes it awesome for pulling code from elsewhere into your project.
      It's not even a virtual machine, those are awesome. JavaScript comes with an entire runtime of assumptions, which is where you get all the async callback whatever crap from. But that's not even the worst part. (But it's bad, seriously bad, this is why Dave put so much effort into excising callbacks from the scripting language for Drummer.)
      No, I'm talking about deeper than that. What do I totally need from my programming language? A complete almost mapping between, say, functions, prototypes, objects, lists, properties, arrays, nulls, nils, unfuckingdefined and every other godforsaken way of doing shit you can think of. But every single one is just slightly incompatible with all the rest so your code is absolutely littered with checks for undefined and special cases and some asshole who thought they were being clever or just didn't understand by copy-pasting from the spamblog that invariably explains the most stupidest, convoluted way to use some random fucking language feature, because Random Fucking Language Features? JavaScript Has You Covered. In Shit.
      So, I don't really need any of that in the language I use to tell Drummer what to do.
      Nor do I need callbacks, or function prototypes, or dynamic live bindings that work almost every time, or god knows what else.
        You know what I will need, I will need this one thing that I just declared I didn't, and I am going to regret this humiliation forever. Irony hunts me everywhere.
      I know JavaScript is a modern marvel, and the things you can do with it in terms of getting performance out of modern hardware are amazing, it's a central point around which a lot of technology revolves, and when you want the power of LISP with the maintainability of FORTH, it should be your first choice.
      I just wish we'd all settled on a more focused subset of the language. We could have stripped out 80 percent of the weird shit and had something just as powerful and flexible for real world problems. This is why Drummer's scripting language appeals to me.
      Update: Here's another post about JavaScript.
    Drummer is fucking awesome
      (5 min read)
      I'll probably change the title of this post. But it's true.
      I think it's because Dave Winer built all the pieces for himself. And he's been at this for a very long time, so he knows where all the inflection points are. When you solve the same problem over and over, from different directions, you get a feel for where you're going to run into trouble, or want flexibility in the future.
      When you start out, you put flexibility everywhere, everything is configurable and there's an infinite number of ways to do it. I once had a team of developers, fresh out of college, working on a content management system that we wanted to be as scalable and flexible as possible. This is the project I learned to watch what your developers are doing, just keep up with it, because they were very excited with their design, which modeled every kind of data in just three tables. (Sigh. We've all done this, admit it. There's no shame. And it's a design that can work, but not in SQL on a server that today we wouldn't use to power a watch.)
      After awhile you get a feel for the data structures that are going to work, and the things that you know you're not going to need to build. If you don't need the flexibility right now, don't add it, it's just one more stupid chunk of code you're going to have to maintain and drag around with you forever until you excise it because this time you're going to do it right. So the flexibility points you choose are absolutely critical in making something like an app.
      And they're even more critical when you're building something like a scriptable app, a framework, an API, a server, a set of interlocking services, protocols, storage systems, content management, designed and working in the real world right now, which is what Dave's built with Drummer.
      Think about that! How do you even fucking do something like that? I know, you start right from the beginning as a genius, and have everything clear in your head like a vision, and you build it. It could take years because there's a lot of parts, but that's how it works, right? Well, holy shit no.
      Here's what you do not do: You do not build something more than once.
      Wait, didn't I just say that part of making something good is that you've built it several times over and now you can do it right? Well, kind of. But the real point is: Programmers are lazy. The absolute best ones abhor doing something more than once. That's what machines are for!
      So what Dave's been doing, sure, he's been iterating with More and Frontier and UserTalk and Clay Basket and suchlike. But he's been absolutely fanatical about Not. Doing. Formats. Over. And. Over. If he figures out a way to serialize something, a way to improve interaction between processes on a machine or services across the internet, he does it once, he does it publicly, and then he uses it.
      Drummer is, when you use it, an entire ecosystem of interlocking services, servers, protocols and formats, all of them documented publicly, running locally and all over the place, and each of them useful in completely non-Drummer contexts. So Dave could build an outliner, and then serialize the outlines into a file format, and make a tool that talks to Twitter, and build a web server, and and then years later build a blog renderer that takes those outlines and turns them into blogs. Each part swappable, each part useable for other things.
      The other part about being lazy, is that you look for things to automate. And the best way to automate something complicated is making lists of instructions, which is programming, which means you want to write code to make your app do things. So you make your app scriptable.
      We already know that deciding where to insert the flexibility takes care and experience, but deciding how the code should read is absolutely critical. I've designed and documented developer frameworks for commercial sale, back when you could make money doing that. Building something for developers to use is extremely hard, because you can't break shit. And the decisions you make about the API you're constructing have a direct impact on how their code will read.
      You will spend 90 percent of your time reading code, even if you spend all day writing code. Being able to look at it and see what it's doing is critical. The fewer stupid syntactical roadblocks you put in front of your developers, the clearer you can make their code, the better. The snippets of code that Dave posts on his blog, where he says "hey look do you see why this is cool", this is what he is talking about. The code is simpler, it is easier to read, and is way, way, way more obvious. That means it's a joy to work with.
      Take a look in GitHub at the source for some of the pieces of Drummer to see what JavaScript actually looks like when you have to deal with callbacks etc. It's a mess! This is why I want Dave to go ahead and pick a name for Drummer's scripting language, because it really is different. JavaScript generally comes with an entire baggage of stuff that is just a giant pain to deal with when all you really want is to do something with the results of a freaking web call.
        (Drumkit, of course, is the natural choice.)
        Update: See here for additional context.
      Drummer is scriptable, and it's scriptable in the right spots, at the right levels of abstraction. In previous posts I've talked about designing a tagging system (built entirely right inside Drummer, think about that!)—and you'll note that I made an awful lot of assumptions. I know there's going to be a very clean, simple way to walk the nodes of an outline, because duh, there is no way Dave hasn't solved that problem a billion times over. I know there's going to be some standard verbs for string manipulation, node manipulation, navigation, and especially getting and setting attributes. And because Dave built Drummer for himself, and is drawing on a lifetime of building scripting languages and APIs, the verbs are the ones you're going to need first.
      So even the fancy version of my proposed tagging system, the one that's walking nodes and gathering things into collections and then updating in a single pass, even that version would be pretty readable, and probably not more than a few dozen lines of code. And I really haven't written much Drumkit code yet, but the snippets I've done are enough to let me see that.
      And how much of that code will be spent on maintaining menus, connecting buttons, building dialog boxes and then displaying them? Well, none. Absofuckinglutely none, because that shit sucks. To add a command to a menu? Edit an outline. Add a button to the icon bar and attach a bunch of code to it? Edit an outline, and put your code right there.
      So what we've got here in Drummer, is basically a lifetime of experience, distilled into code, documentation, protocols, formats—here for us to play with.
      Drummer is fucking awesome.
  November 3
    Let's make a tagging system and describe it briefly
      Now that I've had a chance to think about it, let's slice away the parts that aren't there.
      To tag a post
        Add something like this to the bottom of the post
          Tags
            Drummer
            Drumkit
            Metadata
        Select a tag node (e.g. "Drummer")
          Click an icon to add the tag
            Traverse tags.opml looking for the match
            Ensure a reference to this post
            Make the node into a link node
          Click an icon to remove the tag
            Traverse tags.opml looking for the match
            Remove any reference to this post
            Turn the node back into a regular text node
      Why is it a pair of add/remove buttons now, when before it was just click one button to update tags? Well, I forgot about removing tags. And as soon as you can add and remove things from one place and expect the right things to happen somewhere else, you are deep in the land of syncing, which is pronounced exactly like "sinking" because there is where you will spend the rest of your days. Synchronization of collections across any sort of boundary is just going to drive you insane, this is a well-known fact.
      Instead, we take advantage of the fact that I'm building this machine just for me, so I know when a tag should be added or removed, and I'll make my own pair of buttons to do it. (Or keystrokes or menu items or whatever, I forget all the choices I have.)
      Also, now I don't have to do any outline traversal to find nodes that ought to be turned into tags. In fact, I think I may not even need to set any special attributes on the node when I turn it into a link node. Which means really I'm just adding and removing terms from an index, manually. Which, hey, that's what a tagging system is.
      I also may not need to set any special attributes on the tags.opml nodes, but it'll probably be easier to work with if I do.
    Let's make a tagging system that won't suck
      I've had a few minutes to think about what I described earlier, and after congratulating myself on how awesome I am (try it sometime), I looked for the stupid parts. (Try it sometime.)
      The main stupid part is that, as described, building the blog will take longer and longer, simply because the list of posts grows and grows, and so does the list of categories. Even if I didn't make any changes to any of the tags on any of the posts, every time I push my blog to Old School, my little script will walk a LOT of nodes, and walk them over and over.
      There are a bunch of ways to fix this, and we can use any or all of them.
        Add a flag to the post's tags node that says "we totally already did this"
        Do the update just once instead of updating tags.opml for each tag we find
          While walking blog.opml
            Build a collection of nodes that are going to need to be updated, the gfaType=tag nodes
              Do we need to keep a reference to where we found the node so we can go back and update it for some reason?
                Can I even navigate opml like that, with like a gid for a node? That would be pretty sweet but
                It could cause the destruction of the universe
                It's highly unlikely anybody would build such a thing for the purpose of manipulating opml files in JavaScript
                Seriously it's a tree, why would you build an index into a tree (hehehe)
              Collection should be a set uniqued on the intersection of metadata (ok just the thing I haven't named yet, the cleaned-up-for-url version of the tag)
          Then go off and update tags.opml, hopefully they're sorted similar if you have a lot.
          If tags.opml is sorted different than the collection you built and there are a shit ton (term of art) you'll want a mapping from one collection to the other (nobody would ever really need this)
        Only do the update when it needs to be updated
          This can be harder than it sounds if you want it to happen automatically
          But I am the complete master of this machine I am building, so I know when the tags on a post get created or updated.
          So, give up on the entire "let's walk the tree to find tag nodes and blah blah" and make a new button that, well, walks the current blog post looking for tag nodes, and blah blah... but it only has to look at the post I'm working on, and it only runs that single time.
          Which means the latency between my clicking the cloud-up-arrow button and being able to view the results in a browser will stay as low as I can get it. And I don't have to build some insane cache invalidation system like I totally plan to some day for perfectly valid reasons that aren't insane at all.
            (Why would you build an index into a tree?)
    Let's make a tagging system
      I've got a few minutes, so let's make a tagging system in Drummer! Or at least work out how I could make one.
      Simple goal: Automate updating an outline that contains links to blog posts, organized by category
      Stretch goal: Include the list of tags assigned to a blog post at the end of the blog post
      How to make it work
        Adding tags to a post
          Select a blog post to tag, and then something something—
            Click minus sign
              Type tag to assign
            Naw, use the suitcase button and make it an attribute or something
              Let's call it umm. I dunno. I don't see a default attribute assigned in the docs for this sort of thing. "tag" it is.
              Adding multiple attributes named "tag" doesn't work (you can add several, but when you click the suitcase again, only one remains).
              I dunno if I want to parse a comma-separated list, which is a common way to stick several string values in a single string, but I'll have to if I opt to just include the tag names inline in the blog post itself, like so:
                Tags: Drummer, Drumkit, Metadata
            Or, let's use the fact that we're working with a structured format here, and something like this at the end of the post:
              Tags
                Drummer
                Drumkit
                Metadata
            Then, let's set an attribute on the Tags node so we don't have to recognize it by name. Let's call it, umm, hmm. Using "type" seems a bit presumptuous and prone to breakage, this is something my own script will look for, not Old School. I probably need a prefix I can use for these sorts of things. For now I'll go with "gfa", which stands for "Gary fucking around". gfaType, good enough for now.
        Generating the tags page
          I followed the instructions and added a button to the icon bar that builds my blog. Right now, that code just fetches a URL that tells Old School to rebuild the blog, and then beeps the speaker. I can easily add steps that run before that happens. Here's what that script will need to do:
            Get a reference to opml.blog
            Walk the nodes. With luck there'll be a verb that just calls me back for each node but if I have to descend the tree myself that's OK too.
            Not sure yet which of these is better
              When I find a node that is marked with an attribute named "gfaType" set to "tags", then each of the child nodes will be a tag
                Dunno if I need this
              When I find a node that is marked with an attribute named "gfaType" set to "tag", then that node is a tag
                Processing the tag name
                Text of the node is the name of the tag
                Case insensitive
                Probably strip punctuation
                Clean up for use in a url path
                Processing the node
                I want to turn it into a link node probably
                The script will take the tag name, then generate a URL for the link
                The link should point to something like
                A standalone page of tags
                An anchor to a tag on the page of tags
                A page listing all the blog posts tagged with that tag
                Some combination of the above
                Then, update the tags node itself
                Get a reference to the tags.opml or whatever I call it. This will probably be a public outline that gets included into a standalone page. Or possibly about.opml.
                Walk that outline looking for the node that represents the collection of references to blog posts for this tag
                Match loosely
                Case insensitive
                Match on plain text of tag
                Match on cleaned up for url version
                I suppose I could add something that lets me specify a canonical version and variants but I've done that before and it's a pain. Maybe I can just be better about maintaining my metadata.
                See if the blog post is already in the collection
                Add it if it isn't
  November 1
    Getting selected text in Drumkit
      (I've decided to call Drummer's scripting language "Drumkit" until Dave picks a better one.)
        Update: See here for additional context.
      Since keyboard commands are iffy on the iPad, I figure I'll need a way to do things with the selected text, so I poke around the DW menu and there's an example using a verb that looks close, op.getLineText().
      Normally with Drumkit snippets you just put them on a node by themselves and hit command-slash and Drummer runs it. But to test something that uses the current selection, you need a different way to call the script.
      So, enable the Scripts menu, and add the command there. Highlight a node in the outline, select Get Line Text from my new menu command, and voila, it works. In fact, you can test it on the entry in the Scripts menu itself. I love things like that.
      So, pull up Docserver and go looking for something that will get me the selection. It's got to be possible because Drummer has a "make link" icon. And there it is, op.getSelectedText(). Add that as a new command to the Scripts menu, and... the dialog box is empty, no text at all. I was all set to file a bug, but while getting repro steps—absolutely the most critical part of reporting any bug—I realized what was going on. When you tap on the Scripts menu, that takes the selection focus away from the outline, so by the time the script runs, there's nothing to select. So I can't really report that as a bug.
      But I still want to be able to do it, so let's try putting it in the Iconbar. I have no idea what icon names are available, but the top one is a big plus sign. Turns out, we do in fact have an icon named "minus", and my new "click the minus sign to show an alert dialog with the highlighted text" feature I just added to Drummer works great!
      It is going to be weird working in an outliner for code, but for short snippets I think I can get used to it. For longer stuff I think I will probably still prefer a full IDE.
    Visual Studio Code on your iPad, kind of
      Have a keyboard.
      Go to project in GitHub.
        If you're using the app, click the share button to open in Safari
      Type a dot. Just hit period. That's it.
      Boom! You can use an IDE for navigating that source, with function outlines and everything else. You can't run or debug code, but so far I like it much better than the regular GitHub UI for browsing and viewing project files. (Though I have to say, viewing Jupyter books inline is pretty sweet.)
    Poking around the source code pays off
      This is probably documented somewhere, but one of the things I want to use Drummer for is the ability to publish standalone pages that aren't actually blog posts. Turns out, Old School can do this! The source for Old School is up on GitHub, and what do you know, there are some functions with "standalone" in the name.
      So, here's what I did.
        Add a new node to my blog.opml file, not by using the plus icon like you should when making a new blog entry.
        Use the suitcase button to inspect the attributes. You'll need to set at least two:
          type = page
          relpath = partial path to be used for the URL for the page
        For my experiment, I set the relpath to Someplace
        Build your blog
        Navigate to http://oldschool.scripting.com/TwitterHandle/Someplace
      Here's a link to Someplace.
      I am extremely excited about this, because it means out of the box, more or less, Old School will do a huge chunk of stuff I was afraid I'd need to write myself.
October 2021
  October 30
    Poking around to see what outlines look like in Old School
      Let's find out just what happens when we make something different. My goal is to use Drummer to manage an outline of projects. For example, I just got a new electronic goban and it deserves its own page. But it also deserves a blogpost. Maybe everything should be a dated blog post. But it would be nice to be able to use the default blog renderer (Old School) to render things that aren't blog.opml or about.opml.
      I made a public outline called Things.opml, which sometimes you can see included above and sometimes you can't. I haven't yet figured out what causes it to render fully or just be the title yet, I think it depends on its expansion state when I build the blog maybe?
        Update: I have removed the inclusion of Things.opml above, because I did a bad thing and accidentally turned it into a copy of the DW menu. I don't think this is a good thing to include in a blog post. Also, the things list is going to be too long to include inline, and I still don't have a good grasp of when included outlines get expanded when it goes through Old School.
        The Things.opml outline is still public, but I do not recommend opening it. I think I ripped a hole in the universe. For now, Things2.opml is the new Things.opml.
      I don't know if there's a way to get Old School to render/handle a request that says "render this file as a page", but basically that's what I'd like to be able to do. If I can't get Old School to do it directly I can write some Drumkit to do what I need. I think my final goal is to have something that renders my Drummer outlines into static html files that I can just host somewhere. For now I've set Things.opml as the about page for the blog part.
      Each of the nodes in the outline might be a reference to a separate opml file, and nodes might get moved into their own files as they get bigger, maybe. Not sure where the boundary between page and node is. Probably simplest to just let you navigate the entire hierarchy by clicking around, collapsing and zooming, but it'd be nice to make it simple to link to a page of just the electronic gobans, or a page just for the National TQ-1500.
      (Which, by the way, is basically the only electronic goban, ever. One of my projects is to build a new one, using LEDs for indicators and sensors.)
  October 29
    More Drummer things, iPad edition
      Turn off Smart Punctuation on the keyboard, or else you will never be able to quote a string properly when writing any drummerscript or whatever this language is called. Unless there's a way to manually type straight quotes from the keyboard, maybe that works, but I couldn't figure it out. Typing the standard option-quote gets me Æ and æ instead of curved quotes, so maybe I'll just go with straight quotes everywhere for the time being. This might be annoying, but it's probably not limited to Drummer.
      Possible roots for names for Drummer's scripting language:
        Tap, Bang, Riff, Thump
        Stick, Cymbal, Ride, Hi Hat, Drumkit, Tomtom
        Snare, Kick
        Backbeat, Groove
        Mallet
      I like Drumkit, so that's what I'll call it for now, until Dave picks something better: Turn off smart punctuation or you won't be able to deal with strings in Drumkit.
        Update: See here for additional context.
  October 28
    Teleprompters
      I’ve got LumaFusion and FiLMiC Pro installed, and using the iPad on my lap to control the camera pointed at me on the tripod feels like I’m living in the future. Your camera operator could be anywhere in the world. Also, the iPad includes a robot camera operator called Center Stage which is pretty neat. Who knows, I might get a TV show shot and edited with this rig. Stranger things have happened.
      Turns out you can use CSS to flip text, and there’s a full-on teleprompter electron app, with source. So it’s plausible you could have a “teleprompter this” button in Drummer.
      Really though, I need the teleprompter text to show up on the little $50 refurb Amazon Fire HD 8 tablet I got for this purpose. I don’t need Drummer to run there, just the teleprompter, so maybe what I want is a teleprompter web page that I can point at the URL for an opml file��
      Even without the teleprompter app, it turns out that if you have a teleprompter rig and a spare tablet, you can use it to seriously upgrade your Zoom. Use your phone as the camera and mic, and have the tablet just join the meeting without any video or sound. The image will be flipped left-to-right, but you’ll be making eye contact with whoever you’re talking to. This is actually a big deal, there are specialized rigs just for enabling this when you’re interviewing someone in the same room.
      The teleprompter rig I’m using is basically a small pro model, but it doesn’t need to be made of metal, come in a nice zippered case, etc. Someone could make a plastic version, really it’s just the half-silvered glass and a frame to hold everything in place.
    Today’s Drummer things, iPad edition
      I’ve finally replaced my original model iPad with something more modern, the big iPad Pro. I think I might be able to use Drummer pretty well with it, which means I don’t need a laptop just yet.
      Use a keyboard. Use a keyboard with a trackpad. Mouseover affordances won’t work so you’ll need to remember what the icons do.
      Assign ESC to the globe key. Everybody needs an escape.
      If you increase the font size in the browser, close most of your open Drummer documents, otherwise the screen will jump around as it switches between “not saved” and “saved”.
      Seriously, you will go insane if you don’t use a trackpad. With a trackpad you can drag nodes around on the outline, which is critical because things like command-R for move right will refresh the page instead.
  October 20
    Things I learned today about Drummer
      Here's what I did, which makes sense that it wouldn't work, but maybe it's not so dumb that I thought it might:
        Post something on twitter with my phone.
        Reply to that post
        Reply randomly to either the top post, or maybe some other post, but basically attempting to post a rant but having no real idea how to do it properly, so all the posts get all tangled up in replies and whatnot.
        Observe that this is not what Drummer puts out at all when you tweet an outline, and now I have a tool for doing this, so let's use it.
        Download today's tweets into Drummer
        Delete the tweets from the iphone
        Reorganize the tweets into an outline where they all are sub nodes of the first tweet. One node with 15 child nodes.
        Click the twitter button. My expectation was that it would confirm that I wanted to tweet them.
        Of course, these nodes already had the little bird icon instead of triangles, so clicking the bird button on the left just took me to the tweet itself I'd already tweeted (and then deleted).
      So instead, I made a new outline node elsewhere, then tried copy-pasting things around. This took a bit because I just wanted the text and not the structure, but I discovered command-A selects just the text, so copy-paste will behave like I was pasting unstyled, un-attributed text. This worked fine, I posted my rant, and everything is good.
  October 17
    Lets get all hypertext up in here
      This is an included outline
        Is the conclusion an inclusion?
          It works, so yes!
        Is the conclusion a transclusion?
          I don’t think so. But I’ll need to think a bit to be sure.
    The greatest cartoon I will ever do. I should just hang it up right now. (Quiet, you.)
    The public high wire
      I’m not used to writing in public. I’m having little tiny panic attacks because editing and reorganizing is instant and straightforward. (I was going to say easy, but:, phone.) And it’s instant to see your changes. Except it’s not a preview, what’s there is there.
      I’m assuming there’s a preview capability somewhere, but if not, I can work out a staging area or something. I know all the words are right here in front of me in the outline, but I absolutely depend on a preview. The reason I am going all in on Drummer is that it is scriptable: I can make it do what I want.
      So the reason for the little panics isn’t that I can’t see what I’m doing or whatever. It just drives me nuts when something gets published, and then silently changed. I came up via newspapers, so if you put something out there and you need to change it, you publish a correction. And both the original and the update are out there to keep you honest.
        If anyone is watching this get published live, I certainly don’t mind.
        I doubt Dave��s OPML-to-blog converter-server-thingie, Old School, does this, but you could step through multiple versions of an OPML file at timestamped intervals. ie, schedule stuff in advance.
        Of course this gives you one of my favorite things: a time machine.
        I can also make a button that computes diffs and pushes them to someplace handy. Remember, scriptable. What’s handy? Probably Time Machine-like slices of the whole thing, so a series of cloned roots. But these little leaf node edits are an interesting conceptualization as well.
      Now, I know nobody is reading this as I’m going, so it’s not like I need to be held accountable for these terrible things I’m saying and then cleaning up. Later, when I’ve hooked up all the pieces and this is part of an automatic money-generating publishing machine, and I’m performing for an audience, then it'll matter.
      So, I hit the build blog thingie, pause.
      Type something. Build it again.
      There, now something’s Out There. But what about all the other obvious things I haven’t dealt with, the things that make me look stupid for omitting?
      Will they know that���s not actually the final word, that there might be more to come? Is there more to come?
      Maybe there isn’t more to come. Maybe I really am just that shortsighted, or biased, or wrong. Heck, that’s the entire point of this blog post and I haven’t gotten anywhere near it yet. The point. To quote my dearly missed friend again, “My point, and I do have one…”
      At the end of the previous post, I wrote, “Let’s see what Drummer can do." What I’d intended to do next was see if I understand what OPML inclusion is capable of. But on the way there, before I even got started, I was compelled to write this blog post. Which is the sort of thing a blogger would do. And Drummer is for blogging, right?
      Well, no, not really. Not for me, anyway. My interest in Drummer is building that automatic publishing machine. I’m not a blogger, that’s not me. Every ten years or so I send Dave Winer an email, and apparently, just last week, while congratulating him on Drummer’s launch and making various unreasonable requests, I felt compelled to tell him how I am just so not a blogger.
      So, the entire point of this post is that I was wrong.
      I love being wrong. That’s how I learn new things.
    The machine of a billion moving pieces begins with one part
      I’ve had a website in one form or another since 1994 or so, but I haven’t had a place for my own creative work in 20 years. And I’ve been doing a lot of thinking in the meantime.
      You have to start somewhere, and sometimes things are a bit messy at first. I still do everything on my phone right now, but in the words of a beloved, missed, friend: It’s time to reinvent myself again. Dave Winer’s got a new take on how everything can all go together, and I’m on board.
      Now I just need a computer. There’s no place to set up another iMac and I can’t use the company stuff, so that means laptop: Is $300 worth it for custom function keys or whatever those things are? Probably not. But better speakers? Yup.
      Or, maybe I need a new iPad. It turns out, my original model iPad still powers up and plays games and physically is capable of performing a lot of things, if you go by bits processed per second, screenpainting, etc. I had it running an entire virtual tabletop in Safari a few years back. But it gets no software updates, so I can’t use it for anything useful. For me, useful is:
        PDF reader, for
          Manuals for all my dodgy test equipment I got off eBay
          Scientific papers or anything else in PDF form for any topic I’ve ever been interested in
        Sketchpad, for
          Drawing cartoons
          Making diagrams
          Thinking
        Distraction-free writing
        Games, for the kiddo
      OK, the Drummer UI has some issues on the phone—I don’t recommend it one bit. But any new computer I get won’t be here for a couple weeks, and the phone is right here in my hand, so let’s see what Drummer can do.
Someplace
  Is this, in fact, a standalone page?
  Let's see!
  What if we try to include an outline? Let's see!
  I guess I need to type the title for this node here
    Electronic games
      Electronic board games
        Electronic chess boards
          Chessica
          The King
          Centaur
        Electronic go boards
          National TQ-1500