I had mixed feelings about it. I don’t quite think it delivered on what it promised, but I think it’s got useful thoughts and suggestions in it. There’s a kind of book where I read it and I think, “There should be a second edition that really nails this,” but it rarely happens. Most second editions are of books that nailed it the first time, not books that needed a second version. Anyway, I’m putting Meeting Design in that category.
Here’s an early section that really set my expectations high:
Design is an intangible currency that separates things that matter from junk. Something designed has been given appropriate and actionable consideration, with forethought and research guiding its creation and ongoing evolution.
Meetings are usually not designed. They are rather used as blunt force, expensive but ill-considered tools to solve communications problems.
The author provides this summary of the design process:
- Clearly define the problem that a design should solve through observation and good old-fashioned research.
- Create and consider multiple options, as opposed to sticking to a single solution.
- Select the option assumed to be the best and begin an iterative effort to refine it from a minimum viable concept. This contrasts with spending excessive time visualizing the finished product in every gory detail.
- Execute or “ship” at an agreed-upon level of fidelity so that you have an opportunity to see how the design fares in the real world with real people. After that, jump back to step one as needed.
From these early passages, I formed an expectation of the book: it would provide an idea about how to consider and compare meeting forms, how to measure their effectiveness, and how to improve meetings over time based on iterative review and refinement. I wanted the book’s content and structure to focus on making me good at doing those things. In the end, I don’t think that’s how the book worked.
Instead, the first half was a few chapters describing aspects of meetings, like facilitation, agendas, or managing conflict. These are topics worth covering, but I felt the material was much more about advice than about leveraging these things based on desired outcomes. That theme was there, but it didn’t feel central, compared to things like the advice “don’t fifteen bullets on your slide”.
I would’ve liked to see a clearer division between universal advice (no, you never want fifteen bullets on the slide) and description of the choices one can make to achieve different outcomes (maybe ask questions out loud, maybe take written submissions). Because those two kinds of things were presented together, it was sometimes unclear what was advice and what was a choice. Also, the choice between two options was often provided by showing when one of them was bad, as opposed to the ways in with both could be good or bad. This often came in the form of an anecdote, something like this text, which I’ve written to make my point:
Alice had to make sure everyone knew how to use the new system. Upon getting her thirty team members in a room, she started by asking for examples of flaws in the old system. This led to thirty minutes of complaints about the system she wanted to get rid of. Imagine, instead, that she had stated a few examples in one minute, and then moved on to explaining the new system. This would have been better.
Every time an anecdote like this was deployed, it tended to feel like universal advice, even when it might have been about showing whether a choice was good or bad in a specific circumstance.
I won’t belabor the point further, but: I think the premise was good, and the execution could use more refinement.
Part 2 of the book is a catalog of meeting templates, organized into meetings that begin endeavors, happend during them, and wrap them up. For each meeting, there’s a description of the goal of such a meeting, the means of measuring the effectivness of the meeting, and a detailed sample agenda. It runs about eighty pages.
A section like this could have felt like old hat. I’ve read plenty of descriptions of how to run various sorts of meetings, including many of the ones in this section. What made the catalog of meetings so interesting, to me, was the way in which each one was presented in the same framework. It hammered home that for any meeting, it should be possible to decide on the goal, and that it should be possible to review the effectiveness of the meeting toward achieving that goal. I also appreciated small details in the description of meetings, like the way in which two similar meetings differ, and how techniques for one might confound the success of the other. Also, a number of these sections had helpful pointers to further reading on specific meetings.
These descriptions also often included specific techniques, like “draw a line on the whiteboard and have everyone put stickies above or below it”. These linked back, either explicitly or implicitly, to some of the choices that were discussed or gestured at by the first section of the book. This made the questions of intentional design more clear and interesting.
When I was halfway through the book, I thought it was a bit of a dud, but that it had at least given me some new ways to think about running meetings. By the end, though, I felt I’d probably pull the book off the shelf again in the future to consult the catalog and think about what patterns might be useful for my own meetings.
Finally, there was a good sidebar from Adam Connor, describing the idea of working backward from the final outcomes required to the kind of meeting and meeting process required. This kind of “working backward from the goal” is often the way I like to build things, and I’m not sure I ever really considered applying it to meetings. In retrospect, it’s obvious, but that’s often the way.
With this book done, I am ready to pull down and read the next book off my management and leadership shelf. I’m just not sure which one it will be, yet.
]]>In some ways, I was an ideal audience for this book, so of course I liked it. I don’t think the things that made us a good match are too unusual, though. I think there are plenty of other people who use Python fairly casually, and who could benefit from getting a much firmer grasp on the language. That’s what this book is about. It doesn’t teach you how to write basic Python programs or how to stand up a simple web service. It assumes you know that stuff.
This is good. If you want to write serious Python code, but don’t know Python at all, you can get up to speed very quckly. If you’re an experienced Perl, Ruby, or JavaScript programmer, you can start write reasonably useful and maintainable Python easily. I don’t know how many pages of tutorial you need, but it’s not the 1,600 pages of Learning Python. (I should note that I read Learning Python years ago, in a previous edition. It was a pretty good book, but as with many “Learn Blub” books, it spent a lot of pages on things an experienced programmer in another language knows, or can pick up quickly.)
Learning how to write a function, use a dict, build a class… these are all easy to pick up, and that’s one of the nice things about Python. Doing so, though, we’re often learning just the surface of how things work. This is good! Larry Wall talked about the important of being able to express yourself before you learned the whole language. You start talking in baby talk, and eventually you do grown-up talk.
This book starts off saying, “Okay, look, you know what arrays and tuples and dicts are. Now I am going to explain, in depth, the abstract interfaces on which they’re built. Then, how to leverage those interfaces for better results. Then, how to built your own container types.”
It explains the common decorators you’ve seen a hundred times, but it explains exactly how they work, down to the quirks of Python’s class and instance attribute semantics. It explains typing, in great depth. This means the new(ish) type hint system, but also classes, subclasses, virtual subclasses, ABCs, and named protocols. Dozens of examples are given, maybe hundreds, and they’re all concrete, useful examples.
I think the book can probably be read out of order, but in order, the chapters build on one another remarkably well. Functions are discussed early, but we come back to them for decorators, then for inheritance, then for generators, then coroutines.
The book covers concurrency, not to show you how to make two functions share time, but to show you how to use threads, how to use coroutines, the primitives they’re built on, and importantly, how they can interoperate coherently. It’s not giving you vocational training on how to get the job done. It’s giving you a deep explanation of numerous concepts in Python.
Unsurprisingly, some of my favorite parts of this book were in Part Ⅴ: Metaprogramming. I’ve done a bit of metaprogramming, both in Python and elsewhere. It’s a technique I find really rewarding, but it’s very difficult to get right, and it’s rarely needed. Still, the book gave three chapters to the topic. Two of them gave me a much firmer grasp of things sort of knew: properties and metaclasses. The third (though it came between those two) was descriptors. I knew descriptors were a thing that existed, but I never understood them. Now I think I understand them fairly deeply. Also, after twenty years very occasionally writing Python, I was deeply gratified, through that chapter, to finally understand how bound methods are actually generated!
The class metaprogramming chapter — the last chapter in the book — provides a thorough and (I thought) clear explanation of what a metaclass is. In giving tutorials on metaprogramming, this was always a bit tricky to get across.
I realize that this post is mostly gushing and not much substance. I’m okay with that. All I’m saying is: this book give a deep explanations of many Python features or concepts that you might otherwise be content to just sorta use. That’s my kind of book.
]]>I considered using a walkthrough to get some of the later bits. I’m told the sea diving is cool. I just don’t find it appealing to bother.
Things to note:
It’s got hunger and thirst timers, ugh.
There lots of rooms with the same name. This isn’t that uncommon, but the east-west “Wharf Road” is five rooms all called Wharf Road. It can be a drag.
The game has some in-game time events. That is: You get told “come to a meeting at this place at 9:30”. This felt really promising! It’s used to enormous effect in Majora’s Mask, although I knew it wouldn’t be that good. It’s also part of the structure of Berlyn’s earlier Suspended, where certain events will happen at certain turns. In the end, though, it was extremely tedious. I felt like I had four stand-up meetings, each of which ended with, “Now meet me again thirty minutes from now. The location of that meeting will take twenty-three minutes to get to, so you’ll be bored for seven minutes, but you can’t get anything useful done in that time either.” Bah.
On the other hand, there’s a bit of a gotcha where your watch needs to be wound or it’ll stop early in the game, making it easy to miss appointments. I really liked that.
To assuage your hunger, you can “buy food” at a restaurant where one of those meetings happens. You’re told you buy “a meal”. So much for the evocative economy of Infocom writing!
Next up is The Hitchhiker’s Guide to the Galaxy! I’ve played it before, and I know what I’m in for. I’ll see how far I can get, but as I recall, it’s got great bits and also bits that are very tedious. After that comes Suspect. I’m not enthusiastic. I guess I’m sounding a bit like a sourpuss, but so it goes!
]]>I tried, and found it fairly insufferable. I’m not doing this for science or a deep research purpose. It’s for fun, and this isn’t fun. From the very beginning, I had a bad feeling about this.
“Rik, snap out of it!” cries Tip Randall, bursting into your laboratory. “The alert signal is on!”
You look up from your plans for the SCIMITAR, a top-secret submarine that’s still being tested. It’s designed for capturing marine life on the ocean floor.
You notice the alarm bell on the videophone ringing. Someone’s trying to reach you over the private videophone network of Inventions Unlimited!
(lab center)
You’re at your workbench in the center of your laboratory, a small part of the Signes Research Lab in the town of Frobton. The videophone screen looms overhead, with its alarm bell ringing.Tip is here.
A microphone is sitting on your workbench.
Okay, Rik, what do you want to do now?
❯ answer phoneAs the alarm bell stops ringing, a picture of a woman holding a microphone appears, and you can hear her voice from the speaker. But both sound and picture are fuzzy.
(Your score just went up by 1 point!)
What next?
❯ examine phoneYou can see a fuzzy picture of a woman on the videophone. Maybe you should turn the knob.
What next?
❯ turn knobAh, that’s better! You recognize the woman as Commander Bly, who’s in charge of the Undersea Research Station of Inventions Unlimited, called the Aquadome, just off the Atlantic coast. “Rik! Rik!” she’s saying. “This is the Aquadome calling the Signes Research Lab! We have an urgent problem!”
(Your score just went up by 1 point!)
What next?
❯ quit
This was bad enough. But then this happened over and over:
❯ read logbook
(You’ll find the Logbook in your SEASTALKER package.)
So many things were “go look at the feelies”. I have images of the feelies, but what a drag. It wasn’t fun, it didn’t look interesting, I put it aside.
Next up is Cutthroats — also nautical themed, so I’m wary. On the other hand, it’s by Michael Berlyn, who wrote Suspended, a favorite of mine. (Then again, I noped out of his other game Infidel. We’ll see how it goes.)
]]>I’ve been feeling sort of generally at loose ends of late, and a while ago I went through my list of unfinished projects to see what might be inspiring. There was definitely stuff that I would like doing in theory, but the jury is out on whether I’ll follow through and love it. On the other hand, the Great Infocom Replay seemed like something that would be fun, not too taxing, and that I’d feel good about doing.
I looked at, and lamented, the state of Z-Machine interpreters for macOS, shrugged, and got to work. (I started on Frotz, my old stand-by, but due to terminal problems, I eventually moved on to Yazmin. More on this another time, maybe.)
Sorcerer is the second game in the Enchanter trilogy, which is roughly “Zork except you play a low-level wizard instead of a murderhobo.” When I think of the Enchanter games, I think of the collection of spells with very Infocom names like frotz and yomin. Upon my recent replay, I felt reassured. The game was exactly that.
I say replay, but I don’t think I ever played Sorcerer before, apart from the first twenty moves or so. I would’ve been most likely to have done so in 1991 with the release (and my purchase) of The Lost Treasures of Infocom, but I was more interested in replaying Zork, replaying Suspended, playing the Planetfall games, and maybe Lurking Horror.
On the whole, I’m going to say that Sorcerer was good. It built on Zork’s success and didn’t feel too much like more of the same. It’s still very much of its era, though. It came out in 1984, and it does stuff that by 2024 (and, frankly, by 1988) was really tedious. Here’s what I wrote in my post about Enchanter, the game to which Sorcerer is a sequel:
It has a lot of the same problems as other games of the period, though. The two that gutted me: hunger and mazes. “You are getting hungry” is one of my least favorite things to see in a game. It is a guarantee that I will end up dead and have to figure out how to replay the game in fewer moves, next time. Similarly awful is the feeling of leaving “The Transparent Room” only to find myself in “The Transparent Room” with a slightly different description. It means I’m going to waste half an hour figuring out a maze using the “gather a bunch of items and drop them in different rooms” technique. It’s not fun.
I started playing Sorcerer and groaned when, fairly early, the game said “You’re beginning to feel hungry.” I thought, “Didn’t some game eventually put a lampshade on this problem by giving you a Eliminate All Hunger Forever spell?”
Well, yes, and that game is Enchanter. So great, hunger and thirst go away… but not the need to sleep. Why not? It really serves no purpose. It’s safe to sleep almost anywhere. The only places you can’t sleep, you’d clearly be foolish to try. But also I find that the “you are feeling sleepy” messages are easy to miss, meaning you might eventually fall asleep while swimming. It’s just an annoyance, and not at all a puzzle.
On the other hand, the coal mine provide a much better form of this problem. Once you enter the coal mine, you can’t go back. It’s full of deadly gas, so you will die almost immediately… unless you drink the vilstu potion, which “eliminates the need to breathe”. It only lasts for some number of turns, though, so you’ve got to figure out exactly how to accomplish your mission within that number of turns. Oh, and it’s a maze.
So, mazes are still around. The coal mine is just one of them, and it exposes another characteristic of the game. (I’d like to say problem, but I think that it’s a matter of taste, and not objective.) It’s this: you’ve only got around a dozen moves to solve the area or die, but also the area is a maze. Mazes are generally solved by dropping items in rooms to make them unique, then traversing the exits to figure out the actual room graph. This will take much more than your twelve turns, so you will die often.
“You will die often” is definitely a characteristic of this game. There are a bunch of puzzles you more or less can’t solve without having died trying. There’s a spell to let you view the future, which supposedly can be used to help with this problem… but I never figured out how to use it successfully. Instead, I saved and restored very often. Once in a while, I’d realize that my save game was made after some very early mistake. The most notable one is when I drank the “eliminate need to breathe” potion as soon as I found it. This seemed to make sense: the “eliminate need to eat or drink” potion is permanent, so I figured this one would be, too. Great! I didn’t notice the message indicating that it wore off, and when I got to the coal mine, I realized I had to start over.
I wouldn’t say I can now play Sorcerer straight through without thinking about it, but I can definitely speed through quite a bit of it on auto-pilot, because I had to. This made me feel like a modern Z-Machine interpreter should really provide better command log, replay, and undo/save management than they seem to.
(On that note, I also would love a ‘terp with a memory browser and poke command. I hit some stupid bug at some point, and wished I could just reset the state of something.)
There is also something satisfying about the game’s extreme lethality. I don’t know that I can explain it, but so many random actions result in death that it becomes funny, especially since you’re restoring saves all the time anyway. It’s got some of the gonzo nature of Zork, maybe turned up just a little. There’s a big amusement park, and I think it’s underground. (I think it’s pretty common to confuse aboveground and underground in these games. Was the Zork Ⅱ volcano underground? I think so, but it’s nonsensical.) Anyway, why is there an amusement park? Well, why not? It’s really only there for one very simple puzzle, or maybe two, so it could’ve been anything. Instead, it’s an eight room area with two fully implemented thrill rides that give you a look at the rest of the game areas for no particularly valuable reason as far as I can tell. I love it.
I’ve gotten distracted from my previous train of thought, though: mazes. There’s the coal mine maze, but also another maze, the Glass Maze. This is a three-by-three cube of rooms made of glass. There are no twisty little passages. If you can go east from room A to room B, then you can go west from room B to room A. The difficulty is that you can’t tell where there’s an exit or where there’s a wall. You can solve this maze without dropping items. It’s still somewhat tedious, but it’s a novel kind of tedious, and I felt okay about it. Even better, though, you can use a spell to transform yourself into a bat. With a bat’s echolocation, you can sense where the walls are. The puzzle is even a little better than just that, but this maze was really okay with me.
As with most of these old Infocom games, I’m struck by the great brevity and economy of the text. There wasn’t a lot of room for words, so there aren’t many words. The authors do a good job making it count. Still, I wish there was room for much more. When they do spend more words on something, it seems pretty successful. I had hoped that I’d find that the third game in the trilogy, Spellbreaker, would be a later version of game file, and so be likely to contain more words. Sadly, it’s another v3 game, so will probably be about the same. I’ll find out in about eight more games, though!
Finally, I really enjoyed mapping this game. I don’t know why, it was just satisfying. I’ve always enjoyed making a diagram, though. I did use the Invisiclues for this game in a few places, but I also felt I went through it quite quickly. I wondered whether part of that is that via OmniGraffle, I have much better map-making tools than the average player of 1984. Here’s my map:
Next up is Seastalker. I hope to report on that sooner than eight years from now.
]]>For context, I’ve got four bookshelves. Two of them are novels, philosophy, textbooks, and history. One is board games and RPGs. The last one is mostly technical books, and it’s the one I took photos of. I’d named the files “shelfie 1” through “shelfie 5”, from top to bottom, so that’s the order I’ll go in.
My top shelf is sort of ridiculous. Also, in the last six months, it’s gotten more ridiculous. That wooden box is a Field Notes archival box, and now there are two more of them. They’re nice affordable boxes to old the little Field Notes notebooks that I like using. I have somewhere between 50 and 100 of those notebooks, mostly unused. I need to use them more and buy them less.
Anyway, the rest of the shelf is other notebooks, mostly also empty. At the far right, you can see the blue spine of my extremely limited edition Fastmail staff notebook. There are a bunch of real Moleskines and a bunch of Google-branded knockoffs. There’s one set of notebooks made from stone (I don’t get it) and two nice Leuchtturm1917s, one of which I was given when I retired from running the Perl 5 project.
As for non-notebook stuff, there’s a ceramic Disney Alice in Wonderland that Gloria gave me ages ago, and whose ankles are held together with gorilla glue. Also, that red zip case is “all the cables I need to travel”, more or less. It’s in a transitional period, now. It’s still got a bunch of USB-A cables, and even a stupid micro-USB cable for my dang Kindle.
I am going to stop buying notebooks until I fill more of them. Probably.
Unfortunately, it is here, at the first shelf of books, that I am reminded that my bookshelf is not really organized in any coherent way. I think that when I first loaded it with books, I had a plan, but I don’t know that I stuck to it, and I certainly don’t remember it.
Anyway, you can see…
My Lisp books, of which the most important to me is Let Over Lambda. You can’t learn Lisp from it, but it does really well explaining the concepts behind advanced macros, which means behind much advanced code generation. This is a topic dear to me, and I think the book does really well. It’s a difficult book, and I should probably read it again in a few years. Also, it got a few bonus points because part of what it does is implement Forth in macros.
I’ve got all (I think) of the The Little Whatever-er books. I think The Little Schemer was probably the book that most helped me get my Lisp legs. the others are a mixed bag. I haven’t read The Little Prover yet, but I’d like to. I’m not sure I’d even like to read The Little Typer. I’m curious about Idris and dependent typing, but it’s so thick (compared to the others), and when I’ve glanced inside it, I felt cold. Still, it’s there waiting for me!
Also, both my Prolog books (inexplicably far from one another), and a book on SNOBOL, which remains, I think, the weirdest non-joke language I have done much reading on. The AppleScript book here was a favorite of mine. AppleScript stinks and this book didn’t need to convince you otherwise. It was really well written and made me feel like I could do real work in AppleScript, which I sometimes did. (I’d like the same book, I think, about JavaScript for Automation.)
This isn’t my Perl shelf because I don’t have one. It does have a couple Perl books, though. Pro Perl Debugging was a mixed bag, but I learned things from it. (I am sometimes baffled how little most Perl programmers know about the Perl 5 debugger.) Perl Best Practices is an even more mixed bag, but definitely helped me nail down a bunch of my Perl style opinions. Minimal Perl is not life-changing, but I’ve recommended it often whenever somebody under the age of fifty mentions wanting to write more awk. Finally, Higher-Order Perl is terrific, and I keep meaning to go back and do the last chapter or two again, since they were just a bit out of my grasp when I first read this about 20 years ago. (Woah.)
I haven’t read the Eiffel book yet, for no reason I can name.
Finally, my Silver Camel! This was a gift upon my retirement from managing Perl 5, and it means a lot to me. I’m not much of a trophy or award person, but I felt like this wasn’t a perfunctory acknowledgement that somebody had to get, but a really nice gesture of thanks. It’s gotten a bit scratched in my moves, but I try to keep it looking good.
Before we talk books, though: check it out! A sheet of the rare, staff-only Fastmail Melbourne Office stickers, including fairy bread, a Keep Cup, and more.
As for the books: more dead languages, of course! Starting Forth is a favorite of mine, and I’ve given many copies over the years. It’s a good language to help with computational thinking, and the book is fun. (If you buy your own copy: you can skip the chapter about the built-in Forth editor. It’s obsolete and weird. But it’s also kind of interesting.) The sequel, Thinking Forth, is less great, I think, but I’m still glad I read it.
There are books that I don’t have much to say about: the C books, Unix Network Programming, the LaTeX book. But there’s the Inform Designer’s Manual, which is a very good book about a fairly weird language. (It compiles down to games for the Z-Machine!) There’s ML for the Working Programmer, which I’ve only read the very start of, but mean to read. Thompson’s Haskell book is very good, although I found it very dry. The build to monads and sequencing was slow, but I really said “a ha!” when we got there.
The Perl books ont his shelf are maybe more notable. Perl Debugged and Perl Medic didn’t get the attention they deserved, I think. I’m not sure they’re worth going back to read (unless maybe you still write Perl?) but they were very good at the time. Stein’s Network Programming with Perl is a real gem, even if you don’t write Perl. It really helped me understand why network programming is the way it is. I bet there’s some newer book that does this job now — and I’d like to read it! The pink Programming perl is the first edition “Camel Book”, signed by Larry Wall and Tom Christiansen. Finally, Object Oriented Perl is a good book about writing OO code in Perl, but also just a good book about object-oriented programming. It’s the book that finally helped me understand what objects were all about. Probably there are better books for other people, but it was a big influence on me.
Finally, on the far right is chromatic’s Extreme Programming Pocket Guide, which I really liked, and still think about when I think about how to build software alone or as a team.
So many thick books on this shelf! TCP/IP Illustrated gets a lot more shelf space than I think it deserves. Or, maybe what I mean is: volumes 2 and 3 never really moved me. The first one taught me almost everything I know about how the Internet works. (This is a mixed blessing, because it is (and I am) pretty out of date.) Advanced Programming in the Unix Environment came strongly recommended, but it’s absurdly thick. I am never going to read that book.
The Pragmatic Programmer is a book that I read at just the right time. I bet if I tried to read it now, I’d be bored and feel like it was just restating well-understood things. When I read it, I only sort of understood them.
I think I read The Unix Programming Environment, but I should re-read it. It’s short, and I’ve had a few people tell me how much it changed their lives. and it’s short.
The Mythical Man Month is here, and I think its reputation is well-deserved. Also More Programming Pearls… but no Programming Pearls! Maybe I loaned it out? That book on Algol was surprisingly really good. I still haven’t made it far into Crafting Interpreters, which makes me feel bad. On the far right is a printed and bound Z-Machine specification.
Finally, don’t miss Andy Lester’s Land the Tech Job You Love. It’s good advice, and I will always associate it with the series of conference talks he did on the subject, including a slide that said “cow eye sucker”.
Honestly, this whole exercise has felt really weird. Why are my books organized like this? Why do I have so many that I haven’t read? Why am I posting this? I don’t know, but I guess I’m just happy to be keeping busy. It’s well below freezing outside and I don’t like being idle. The last shelf does not bring me to any realization about my books or their organization. It’s just more books.
On the far left is a big deal, Object-Oriented Software Construction, a book from the late 80s, about OO programming. Its author, Bertrand Meyer, was the creator of Eiffel, and so also the author of that Eiffel book on shelf two that I didn’t read. I also didn’t read his book Reusable Software, right on this shelf. It was a gift from my friend Stevan. He moved to Europe and before doing so handed me a big box full of programming books that he (correctly) thought I might like having. Also, he drove down from Connecticut to do it. What a guy!
If you squint, you can see Programming with curses, which of course I never
bothered reading because I don’t write C. There are two books on make
, and I
read the O’Reilly one. The eXtreme Programming eXplained book was another
important one for my thinking about software development. I’ve since picked up
the second edition, but not read it yet.
Applied Cryptography was a gift, and I read a respectable 20% or so of it. I don’t know that I’ll go back, but it was clearly a good book. Model-Based Development was written by one of my dad’s frat brothers, but actually does look good. I’ll get to it, maybe. The Dragon Book is here, but not because I planned to write a compiler. I just took it when we moved from an office to a co-working space ten years ago. I didn’t want it to get lost. Finally, Software Tools (in Ratfor) and Software Tools in Pascal. The first one was good, and the second one got us the excellent paper Why Pascal is Not My Favorite Programming Language.
Lately, I’m mostly reading technical books on O’Reilly Learning, either on my desktop monitor or on my iPad. This is nice because I can have the text in front of me while I edit code. It’s not nice because it’s easy to be distracted by everything else on my computer. Also, it’s harder to sit in the park and read on an iPad. Maybe when the weather is better, I’ll try to pick one of these to read through while sitting in the sun. Maybe one of those Bertrand Meyer books, or ML for the Working Programming. Something old and dead and without any direct application. That sounds like a nice time.
]]>One of the more recent updates to Unicode’s emoji repertoire is SALUTING
FACE
, meaning that there is now an emoji equivalent to the ASCII o7
. (Let’s
not get into the mirroring of the image right now, I have more serious topics
to discuss.)
Here’s the saluting face emoji in Apple’s emoji set:
It’s a pretty reasonable emoji in the “yellow face just trying to live its
life” category, which is a strong category to start with. It also makes clear
once and for all that the yellow face is not a marine, which is one less thing
for me to wonder about. The thing is, when I started using this emoji in place
of o7
, something started to nag at me. Visually, I wanted this to be “right
half of yellow face’s face, with saluting hand”. It just didn’t seem like it
was half the face, though. It seemed like at the far right edge, the tangent
was sloping down, showing we were past the center. After days of squirming and
feeling uncertain, I finally looked into it.
Well, there it is! The saluting face is clearly more than half of a standard
yellow face. Also interesting is that NEUTRAL FACE
’s mouth is far broader.
I think this is more evidence to my long-held claim that it’s hardly a neutral
face. It’s clearly an expression of suppressed annoyance, and probably
somebody vetoed STOICALLY SUFFERING THROUGH NONSENSE FACE
. Meanwhile, the
saluting face is wearing a truly neutral expression, as you’d expect from
someone on-duty and saluting.
I still liked to think we were seeing just half of saluting face’s face, though, and I mocked up an emoji that shows us the other half, maintaining proportions.
This is now the :salutes:
emoji at work, and it sees a fair amount of use. I
am glad to know that I have contributed something to our work culture, and
especially that it is a way of showing one respects one’s duties.
Also, I took this opportunity to start logging the things I watch in Letterboxd, at least until I get sick of it. My October 2023 diary will give you a bunch of the information in this blog post, but so far without any kind of rating or commentary. I also populated some, but not all, previous years’ horror movie months. I may get around to doing the rest, we’ll see.
Despite using Letterboxd for keeping my viewing diary, I think I’ll link to IMDB below. The web interface for Letterboxd’s cast lists is terrible, while the mobile one is just fine. This bugs me.
Okay, here we go!
This has been in our list for a while. It’s got subtitles, so it’s been repeatedly bumped down in priority. Often, a horror movie is something we watch when we’re only partly present, and subtitles require more attention. Horror Movie Month can be a good time to catch up on these.
Anyway: a woman, paralyzed from the waist down, is given a creepy Advent calendar. Every day, when she eats the candy, something bad happens to somebody else. Often, something good happens to her. It’s Button, Button, sort of.
I thought it was pretty good, but the ending was annoyingly ambiguous. I get it, people love to make ambiguous endings, but I do not generally enjoy them. Or, maybe it’s: I enjoy when the filmmaker lets us imagine what the world is really like, but I don’t enjoy when we have to decide what the character would’ve done.
Two movies in one day! This was a documentary about the various adaptations of Stephen King’s writing into movies. I have a category of documentaries that are interesting, but don’t really change how I think about anything. This was in that category. I enjoyed it, but it was just a diversion. That’s fine!
It did give me the idea to make a big checklist of King adaptations and try to watch them all. Future project!
This movie is ridiculous, and I like it. Pamela Springsteen is weirdly great as the killer. Sleepaway Camp Ⅲ was filmed at the same time as Sleepaway Camp Ⅱ, so it’s nice to have some continuity of feeling. I think it represents a lot of what’s best in the goofy just-for-fun slashers. That said, it’s kind of not great. It’s just fun.
We’d had this in our list for quite a while, and Gloria said she’d heard good things in some horror documentaries. It was pretty good. More subtitles! Basically, it was a haunted house. I remember a little bit of it, but not a whole lot. I think that means it was probably just fine.
We like a good horror comedy. This one, I think, was okay. I also think I wasn’t the target audience, so I’m not the right guy to ask. I liked the cast, and maybe I should look for them in some other things.
Messiah of Evil made its way onto our to-watch list because it was on a “best overlooked horror movies” list, maybe on Polygon. It wasn’t good. It had a pretty weird vibe, which I appreciated. I didn’t really buy it was a critique of consumerism, or at least as an effective one. There are better Lovecraftian movies, better zombie movies, and better movies criticizing society.
But now I’ve seen one more cult classic.
When this movie came out, it felt like it was everywhere. It made a lot of best-of lists, and people talked about it was a breakthrough. Maybe I should’ve watched it ten years ago, but I am so, so burned out on shakycam. I want to see some found footage movie where all the footage comes from fixed cameras. Lots of security camera footage. Parked car dash cams. That kind of thing.
Anyway, an anthology movie is like a short story collection, and I like them both for the same reason: the good stories are good, and the bad ones are over soon. This had a couple good pieces and a couple bad ones, and I liked the good ones. I just wish they weren’t shakycam!
My main complaint is probably that the framing device didn’t end up tying things together enough. (If there’s no framing story, I do not require things tie together!) There are maybe five sequels to this, and I’m a little worried that it’s going to turn out that they keep pretending there’s some cool underlying story, but there won’t be.
I’m not sure I liked it enough to watch many of them, though.
This is sort of a sequel to the 1982 Slumber Party Massacre. It was great.
The original was first written as a send-up of slasher movies and their misogyny, but during production was reworked to be a more traditional slasher. This movie brings back that stance. We see a bunch of shirtless guys having a pillow fight and spraying each other with beer. There’s a long, long scene of one guy showering.
It’s also fun as a goofy slasher movie with decent production values. I think I’d suggest watching the first two originals, then this one. (I have no recollection of the third movie!)
Octavia Spencer (great as always) plays a “just kinda off” woman who starts helping a bunch of teenagers buy booze, and to have a place drink it. Thing is, she’s just kinda off. The movie takes a couple left turns. It was probably one of the better things we watched, and I recommend it.
This was on a few “best of 2022” lists, and I’d seen a trailer at some point in the past that looked good. Despite the previous exposure, I somehow hadn’t realized it was an Australian movie until it was playing and I heard the accents. Woah.
Premise: there’s a ceramic hand, and when you hold it and say the magic words, you see a ghost, and you can let them possess your body. This gets used as a party trick by stupid teenagers, because stupid teenagers are stupid. “You can’t hold it for more than ninety seconds”, but somebody does.
It was good!
This is just Hatchet Ⅳ. It wasn’t great. I liked some of its ideas, especially the “trapped in a crashed plane” bit. Mostly, though, it just wasn’t good. I still like seeing Kane Hodder get work, and I liked Parry Shen.
I’d give it a pass.
Look, this wasn’t a masterpiece, but it was a lot of fun, and if you think you might enjoy it, I think you probably will. Thirty years after 1980s slasher event, the child of the survivor girl goes back to that era and tries to prevent the whole massacre.
It’s a little bit Happy Death Day, a little bit Back to the Future. Just my cup of tea.
Well, despite not loving V/H/S, we decided to watch the first sequel. Like the first one, it had its moments, but it wasn’t great. Some of the short films in it were good, though. How about somebody makes a new V/H/S movie that’s just the best shorts?
I am not sure I will watch any more of these.
Look, I knew this movie would not be great, but I hoped it would be fun. It was occasionally fun, but not worth the time.
A movie based on and partly funded by a retail chain wasn’t great. Who could’ve guessed?
I’ve seen Christine before, but I wanted to see it again, especially after watching the King on Screen documentary. It was still really good. It’s very of its time, but in a good way. I had forgotten how good the cast was! Keith Gordon, as Arnie, is just terrific. The rest of the cast was great, too, and I especially liked Robert Prosky as Darnell, the foul-mouthed owner of the garage where Arnie repairs Christine.
Also? Great music.
I really like David Cronenberg, and this is one of the few movies of his that I hadn’t watched yet. I also like Jeremy Irons. How could it not be great?
Well, it was great! I feel like maybe someday I’ll watch it again and get even more out of it. For now, though, I just thought it was a really well-told story. (At one point, I said “there’s not a lot of Cronenberg stuff in this!” Thirty seconds later, Dr. Mantle brought out his “surgical tools for working on mutant women.” So, there was still some.)
When I was a kid, we went to Blockbuster Video all the time. We never got horror movies, but some of the boxes stuck with me. This was one of them. I’d seen it before. It wasn’t great, but I enjoyed it. It’s by Jim Wynorski, one-time king of exploitation movies (and sometimes soft-core pornography).
It’s the ’80s, some young people decide to stay in the mall’s mattress store overnight. The mall has recently rolled out security robots. Lightning strikes the mall and the robots become murderous. You can imagine a lot of what happens from there on out.
This is a telling of the Frankenstein story, built around themes of systemic racism and cycles of violence. It was good, and I enjoyed it, but I wish it had been a miniseries. I felt there wasn’t enough time to get a good sense of the characters, setting, and relationships. Great cast, and I was reminded how good Chad L. Coleman is.
I really like Frank Henenlotter. The Basket Case movies are weirdly great. Frankenhooker, too, is great, but in a very specific and weird way. It’s a good exploitation film about an electrician who is an amateur doctor and would-be Frankenstein. When his girlfriend dies, he wants to bring her back, but he needs body parts, so he goes looking for bodies. Also, he creates “super crack” to entice people.
The best thing about this movie is the north Jersey accents.
Deeply meh. I didn’t care about almost any character in this, and I felt like its weird ecumenical approach to the exorcism was less, not more interesting than the very Roman Catholic one of previous movies.
Leslie Odom Jr. was great, though. No matter how much I didn’t care about anything else, I cared about his character, because anything that guy said, I took seriously. I should find out what else he’s done, beyond the obvious.
This movie is stupid and I love it. It really leans into the ridiculousness of the original Child’s Play premise and has no shame about it, and that’s just what I want in a movie like this. Also, Brad Dourif and Jennifer Tilly are great.
I think Cult of Chucky remains my favorite Child’s Play movie, but this one is up there. (This was my second time watching this one.)
I saw this movie when it was new in the theater. It’s still great. Rob Reiner is such a good filmmaker, and across so many genres! It’s basically a two-hander, although some of the small secondary roles are great. (The sheriff!) James Caan is good, but Kathy Bates! Her Annie Wilkes is, to me, one of the all time scariest movie characters.
There’s a killer clown who never speaks, but he does do a buch of murder. It’s set in a nameless city that I choose to believe is Jersey City. I was pretty torn on this one. I appreciated the “Why? Because I said so, that’s why” nature of things. The movie did not need to explain anything to you, and didn’t make bones about it. I also thought David Howard Thornton did a really good job of being a creepy clown with a great range of clownish expressions. In the end, though, it just wasn’t great. I’m not sure I’ll watch the other movies in the franchise.
Shudder recommended this as a cult classic. I thought it was great (but terrible), and a real gem of the 1980s “weird bad stuff happens, and the justification can come next.” People attending a new fitness center keep dying. The script mostly makes sense, if you don’t look too hard. There are a half dozen possible causes of the death, including both ghosts and computer error. Somebody gets killed by using a pec fly machine, and I think it’s because he has somehow strapped his arms into it?
Anyway, it was very stupid and I liked it a lot.
The synopsis for this movie includes the phrase “a disgraced children’s puppeteer”, which starts things on a pretty weird note.
It’s a strange movie, and I don’t think it’s right to think of it as a horror movie in the same sense as so many other things on this list. It’s a psychological horror story about a man who has had a difficult life and now comes home to the absolute disaster of a house he grew up in. It’s very slow paced and deliberate. I did like it, but I’m not sure who I’d recommend it to. I think I liked it more because it was committed to being what it was, more than because it was extremely effective.
This was my second time watching this movie, which I remembered in part, but also was clearly mixing up with The Void in my memory. It was good. Brian Cox and Emile Hirsch play father and son coroners who are brought a really weird body to examine. It’s late at night, there’s a storm coming in, and as the night drags on, things get weirder and weirder. I thought it struck a really good tone, and the guys try to stick to “everything can be explained” until they finally say, “let’s just get the hell out of here”. Also, I thought it ended well, which a movie like this could easily fail to do.
Only barely a horror movie, here at the end. We have been skeptical of Kenneth Branagh as Poirot, as we’re big fans of David Suchet’s long run as the detective. Still, this one looked fun, and we’d heard good things. Our verdict: it was okay. Branagh was fine, but no Suchet. It was a little too dark — like, the lighting. There were some weird plot holes. Still, it was just fine. I’m not in a rush to watch the other Branagh Poirot movies yet.
Above, not every day in October is listed. We also watched the fourth season of Creepshow, which was okay. (We enjoy Creepshow, even when it’s not great.) Sometimes I think there are only one or two good episodes, but it’s just fun even when it’s bad. I like its attitude.
We also watched The Horror of Dolores Roach. It’s a spin on Sweeney Todd, with Justina Machado as the Todd role. She kills people and her friend makes them into empanadas. It was good, with a balance of tension and comedy. The framing device was weird, but worked. I’m not sure what I think about the implication that there will be another season, but I liked the one we got.
I’m sure between now and October 2024, we’ll watch lots of horror movies, but probably I won’t write about any of them, and you’ll have to wait until then. We do have a few things queued up for Christmas, though. Also, finally we get a new Thanksgiving horror movie this year: Thanksgiving. There really aren’t enough of those.
]]>I work on a bunch of different hosts, from my laptop to my Raspberry Pis to work systems, and others. At work, hosts have different color prompts by datacenter, and I thought this was a good way to remind myself where I was running my commands.
First, I made a little shell program called .sh/host-color
:
HOSTNAME=`hostname -s`
if [ -z "$HOSTNAME" ]; then
RJBS_HOST_COLOR=247 # no hostname! dim unto death
elif [ "$HOSTNAME" = "dinah" ]; then
RJBS_HOST_COLOR=141 # lovely lavendar
elif [ "$HOSTNAME" = "snowdrop" ]; then
RJBS_HOST_COLOR=81 # an icey blue
elif [ "$HOSTNAME" = "snark" ]; then
RJBS_HOST_COLOR=202 # orange you glad I picked this color?
elif [ "$HOSTNAME" = "wabe" ]; then
RJBS_HOST_COLOR=66 # the color of moss on your sundial
# ... lots of options elided
elif [ -e "/etc/listbox-version" ]; then
RJBS_HOST_COLOR=46 # any Listbox host, Listbox green
else
RJBS_HOST_COLOR=201 # bright pink; where ARE we??
fi
Then it’s easy to use that variable in a bunch of places to remind yourself of context. The most important for me are tmux config and shell prompt. That way, I can see when I’ve ssh’d into host A from a tmux on host B, like this:
In my .zshrc
:
export PS1="%{^[[1m%}%F{$RJBS_HOST_COLOR}%m%f:%~%(!.%F{red}#.%F{46}$)%f%{^[[0m%} "
In my .tmux.conf
:
set -g status-right \
" #[fg=colour238]#[bg=colour0]▛#[fg=colour$RJBS_HOST_COLOR] #h "
…and that’s that!
]]>I should say up front: I haven’t really tried to use the default touch programming. That is: I haven’t gone into the Nanoleaf iOS app to set events onto touch events. I know that isn’t what I want to do long term, and I didn’t have any good ideas about how to use it for diagnostic purposes. I do know that the touch sensors seem to work to some extent, because when touched, the panels brighten.
Anyway, here’s the deal: There’s an HTTP endpoint in the Nanoleaf Shapes API
that provides you Server-sent
events providing updates on
the device’s status. I don’t like server-sent events. It’s fine, I know how
they work, and they’re not terrible. It’s just that I don’t like reading the
spec. This is a me problem, not a server-sent events problem, but there it
is. Anyway, your client needs to GET
/api/v1/{your-auth-token}/events?id=1,2,3,4
and read chunks. The id
parameter doesn’t have to be exactly that. It’s a comma-separated list of
event types. What are the event types? Well, at first, it depends on which
part of the documentation you believe.
Section 3.5.1 says:
For example if a client wished to register for the state (id=1), layout (id=2) and touch (id=3) events, it would sent the following request:
Section 3.5.2 gives a table with the following ids:
- State: 1
- Layout: 2
- Effects: 3
- Touch: 4
In the end, I don’t think this is actually a contraction, just a terrible choice. Here’s why…
Server-sent-events are sequences of key/value lines separated by blank lines. So, you might get this:
id: 1
data: {"events":[{"attr":1,"value":false}]}
id: 3
data: {"events":[{"attr":1,"value":"Beatdrop"}]}
That’s two events. The id
value is meant to let you synchronize with the
server. When you connect, you’re told the last event id, and then each
subsequent event tells you its id, and you can keep up to date with the event
stream. In the Nanoleaf API, that’s all thrown out the window. The id
field, here, is actually event type id. It tells you what kind of event is
described by the JSON in the data. Why abuse the id
field for this instead
of putting it in the JSON? I don’t know.
Anyway, it could make sense that the id
query parameters were for one kind of
type and the event ids were a different id type. It doesn’t appear to be the
case, though. If I want effect events, I subscribe with the id
parameter set
to 3, not … well, they didn’t give a value for effects in the parameter type
definition. It seems to just be an error. Now we know, and we’ll trust §3.5.2
over §3.5.1.
Back to the events! Being able to get notified when the layout, state, or active effect changes sounds like it could be useful for some things, but I had no need. I wanted to know about touch events. Why? I don’t know, it just sounded neat.
A touch event, like every other event, is provided as JSON in the data attribute of the server-sent event. Here’s an example:
id: 4
data: {"events":[{"panelId":-1,"gesture":5}]}
id: 4
data: {"events":[{"panelId":-1,"gesture":4}]}
The gesture
key is another numeric id, with the following definitions:
When you get a tap, the panelId
is the panel id of the tapped panel. When
you get a swipe, the panel id is -1, because a swipe is defined as swiping
across two or more panels.
I have never seen the server-sent events provide a tap event. Also, I find their reporting of swipe events very unreliable. They’re reported with a large delay, and often not reported at all. I’d say the other event types have delays also, but I find it less of a problem that there’s a 700ms delay between power off and power off event than that there’s a 700ms delay between touching the device and seeing the touch event.
This was not going to be useful. Fortunately, there’s a touch stream, where you can get “fine resolution, low latency” touch data streamed to you.
It works like this. You still have to start up your event stream connection,
even though you won’t be reacting to the events. It’s just a way to tie the
duration of the streaming to something else. When you make the request,
though, provide the HTTP header TouchEventsPort
. This tells the Nanoleaf
controller where to stream the events. It will send datagrams to the
requesting IP at that port, and it will send them in real time. Sound great?
Well, in my experience, it isn’t.
First, I had some frustration setting up the whole program, all of which was my fault. I have a weird mental block about quickly writing UDP listeners with IO::Async, and I don’t know why. Fortunately, I recognized that I was hitting that problem and switched to plain old Socket, which worked great, except I needed to initiate the long-running HTTP request with curl. Silly, but fine. None of this is why I found the end result unsatisfying.
The first problem is the binary format of the datagram. Why aren’t the datagrams JSON? My guess is that the onboard processor isn’t up to real time encoding of arbitrary multi-panel touch events into JSON, and I can respect that. Who doesn’t enjoy writing a little binary data parser once in a while, right? The problem for me came first from the documentation. Again!
The documentation says the format of the datagrams is as follows:
<(touchType = 3bits |
touchStrength = 4bits)1 = 1B>
<(touchType = 3bits | touchStrength = 4bits)2 =
1B>
<(touchType = 3bits | touchStrength = 4bits)3 =
1B>
<(touchType = 3bits | touchStrength = 4bits)4 =
1B>
.
.
.
<(touchType = 3bits | touchStrength = 4bits)_n
= 1B>
First off: what? The first line seems like it might make sense: three bits for “touch type”, then four bits for “touch strength”, then a set bit. Repeat. But then the second byte replaces the 1, which I took for “a set bit” with a 2. You can’t have 7 bits, then a 2, and have it make one byte. What??
This is okay, because the documentation continues, contradicting itself but providing much more useful information.
The first 2 Bytes represents the number of panels that are currently undergoing a touch event. After that follows nPanels number of 5B packets, each packet representing touch data for that panel.
The first 2B of the packet represents the panelId of the panel that is currently undergoing a touch event. The next 1 byte is a combination of the Touch Type and Touch Strength:
[ diagram ]
The last 2 bytes represent the panelId of the panel swiped from only in case of a swipe event. This value is otherwise set to 0xFF
Okay! Now we’re getting somewhere. We get (2 + 5n) bytes, where n is the number of touched panels. The first two bytes provide n. Great!
Now we just need to know how to interpret the per-panel touch type and strength, helpfully given in a diagram. Here it is:
Oh.
It looks to me like this is another unfortunate problem with Nanoleaf’s API site renderer. The table header is probably meant to have markers for “this header spans n columns”, but it doesn’t make it into the HTML. So, which bits are part of which field? Hard to say. The good news was that I did receive datagrams, so all I had to do was inspect the packets, right? This was pretty easy, basically a pretty printer plus this:
my $sock = IO::Async::Socket->new(
on_recv => sub ($self, $dgram, $addr) {
state $counter = 1;
Nib::TouchUtil->dump_dgram($dgram, $counter++); # <-- pretty printer
},
);
A couple events get dumped like this:
I got everything working, it seems, but it’s really not satisfactory. First
off, I can tap as much as I want, I get “hover” events. I can get a swipe (as
you can see in the diagram), but basically never a tap. I hoped that this was
going to turn out to be a misunderstanding of that confusing packet definition,
but I don’t think it is. You can tell an event is a swipe because the last two
bytes aren’t 0xFF. Given that, the type/strength byte needs to have an 100
in it to represent the touch type for swipe. That only happens in one place in
swipes: the right three bits of the left nybble. That leaves the right four
for touch strength, which never seems like a useful value.
Beyond that, the delivery of these datagrams isn’t reliable. I don’t mean “UDP isn’t reliable”, I mean that it feels like the Nanoleaf controller only sends these events when it feels like it. If I hold my finger on the panel, I get repeated hover events… sometimes… for a while. It’s not terrible, but it doesn’t feel like something I could really rely on for anything but a goof. For a goof, though, I’d have built it to show somebody, and I wouldn’t want it to fall flat!
There’s one more problem. For a while, during development, I stopped getting the datagrams at all. It happened when I was trying to move the HTTP event stream code into Perl, and my initial theory was that initiating the HTTP request with Perl wasn’t starting the streaming datagrams, but initiating with curl was. I tested this over and over, I fired up Wireshark, I fiddled with parameters, IP version, I asked friends. Finally, I did some things in a different order and realized that as best as I could tell, it didn’t matter what HTTP client I used. The problem was that I needed two HTTP connections active for the UDP stream to begin. It was easy to reproduce with a bunch of different combinations.
A week later, that symptom was gone, but the weird and unreliable datastream was still there. I was never particularly attached to doing anything with the touch events, so I just gave up on the branch and decided my next hunk of work would be about putting colors on panels. At least I made a pretty packet dumper!
]]>