Haupz Blog

... still a totally disordered mix

Tár

2024-10-09 — Michael Haupt

It's been a while since this was on the big screen. I still want to recommend the movie Tár. A masterpiece - I was completely captivated.

What helped make this happen was not just Cate Blanchett’s impeccable acting, but also that the story unfolds in a setting I’m at least a bit familiar with. I found the dialogues about music to be at a rather elevated level of nerdiness that I greatly enjoyed. Similarly, the depiction of how sheer power plays out in the highest spheres of cultural business struck some cords ... I’ve had my own introspections into that.

This is an absolutely fantastic movie.

Tags: movies, music

Marvel Dice Throne

2024-10-04 — Michael Haupt

Marvel Dice Throne is a game involving rolling dice a lot (one might guess that given the name), and it has a nice deck / character building aspect, too.

Each player picks one of eight Marvel characters. For each character, there’s a whole collection of character board, individual cards, status tokens, and dice. That means the game’s box is sizeable.

The point of the game is to let up to four characters engage in a battle wherein they, bluntly spoken, smack one another around the place by applying various super powers. For my test, I chose to let Captain Marvel play against Black Panther - for no particular reason.

Each of the character boxes contains, as mentioned, a selection of items and cards. These are all set out to prepare the game. In the image below, you can see the setup at the start of the game. The characters start out at full health (indicated by the oblong counter to the upper left of the character tableau). They also have a certain amount of combat points (CP, indicated by the round counter). Each character also has a starting set of four cards.

The rules are learned quickly: in each round, the acting character first does some deck building by selling and playing cards (CP are the currency). Next, the character attacks an opponent, who can deflect (some of) the damage by activating defensive skills. This is followed by another round of deck building to wind things down. Each character has special abilities, which are depicted by special cardboard tokens. These add a lot of spice to the game, and make for some surprises.

So far, so good - it’s plain and simple. The game is fast-paced and quite a lot of fun, because the combinations of cards and special abilities, together with the random element added by the many many dice rolls, make for many variations. I can wholeheartedly recommend it.

Captain Marvel won this round, by the way. Narrowly.

Tags: games

PlanckForth

2024-10-03 — Michael Haupt

I had shared some discoveries I had made in Forth territory. Since these systems of minimal abstraction really fascinate me, I took a deep dive into the PlanckForth implementation and dissected the 1 kB ELF binary down to the last byte.

This is indeed a tiny Forth interpreter that does just the most basic things in machine code. It provides the foundation for a very consequential bootstrap to be executed on top of it. The bootstrap builds the actual Forth language from first principles in several waves.

In case you’re interested, here are the binary source and bootstrap with my comments. Note that I stopped commenting in the bootstrap once it gets to the point where the minimal Forth supports line comments.

What next? Part of me wants to build a handwritten RISC-V binary for the basic interpreter ...

Tags: the-nerdy-bit, hacking

More Forth

2024-10-03 — Michael Haupt

The Forth programming language is a thing I’ve previously written about. I recently came across this little gem of a talk, wherein the author points to some interesting resources about Forth. In particular, the slides put emphasis on how minimal a Forth implementation can be.

The point about Forth is that it heavily depends on threaded code. That’s a simple technique to implement an interpreter on the bare metal. In a nutshell, code to be executed by a threaded interpreter is mostly addresses of implementations of logic, that the very simple interpreter “loop” just loads and jumps to, following a “thread” of addresses through its implementation.

Indeed, Forth source code consists of just “words” that are concatenated to express semantics. These human-readable words are mere placeholders for the memory addresses where the words' implementations can be found. In other words, a Forth compiler is simplistic: it boils down to dictionary lookups.

To demonstrate the minimalism, the PlanckForth interpreter is just a 1 kB hand-written ELF binary. The syntax of the basic language this interpreter understands is a bit awkward, but sufficiently powerful to bootstrap a full-fledged Forth in just a couple hundred lines.

JonesForth is a richly documented Forth implementation. (You’ll have to go through the snapshot link to get the source code.) Reading the code is highly instructive.

Tags: the-nerdy-bit, hacking

Historical Source Code Every Developer Should See

2024-09-21 — Michael Haupt

This piece lists some historical source code that today’s engineers, in the opinion of the author, should read and know. The artifacts in question are the WWW demo source code, an early C compiler, pieces of the early Unix research code bases, the first Linux release, and Mocha, the first JavaScript engine.

While all of these (maybe, and forgive the snark, with the exception of Mocha) are relevant, I cannot help but wonder about the author’s rationale for choosing these particular specimen. The author argues these “built the foundation of today’s computer technology”. I beg to differ.

Graphical user interfaces are quite a thing in today’s computer technology, one should think. These owe a lot to BitBlt, the Xerox Alto machine, and, consequently, Smalltalk (that programming language had an IDE with a GUI back in the 1970s). So, for source code, I’d add to the list this memo from 1975 describing BitBlt, and the Computer History Museum’s page on the Xerox Alto source code.

Tags: hacking, the-nerdy-bit

Avoiding WIP Creep

2024-09-16 — Michael Haupt

Recently, I had described how I arranged my work tracking to deal with high amounts of WIP, or rather, after hitting rock bottom with WIP.

But how did that happen? I’m normally good with prioritisation. I could admittedly improve my delegation skills, but feel there’s a good balance. WIP just seemed to accumulate over time. At some point, this WIP creep became too much. What led to the accumulation, though?

I believe it’s ultimately dependencies, combined with an inability to fully cover each WIP item. Let me explain.

A pattern that I observed is this. I start looking into some matter, accepting it as a WIP item. At some point, I need input or a contribution from someone else - there’s a dependency. In some cases, I can drive the item forward by doing as much as possible of the contribution I need myself. In cases where that’s not possible (due to expertise, knowledge, authority, or whatever), I’m unable to continue. The dependency stalls for as long as it takes to obtain the required input.

If I’m disciplined and have a WIP limit, that means that, at some point, I’ll start idling because I have stalled dependencies on a majority of (or all) WIP items. So my natural tendency to get stuff done kicks in, and I accept new WIP items. Loop back to above, and there’s the downward spiral.

No one’s to blame - we’re all busy and have many things to do. Not all dependencies can be resolved immediately. So the next question is: how to avoid WIP creep, and what to do instead of idling and accepting more WIP?

Let it be clear - accepting more WIP that comes as requests is often inevitable (at least for me). The role demands paying attention to many things. (There is something to be said about how to bring down the number of things to actively pay attention to.) What seems to be more relevant is that allowing things to rest and waiting for them to move creates the false impression of more time being available. This is the “void” that new WIP eagerly fills.

So what can be done instead of waiting? Taking action, of course. That piece of input I’m expecting someone to deliver: can I get that myself by doing some research (and learn something new along the way)? The piece of work I think I need someone else to do: can I do that myself (and take some of the load off of that other person)? Possibly even more so than mentioned above - in other words, by doing more than possible?

Bottom line: if I have a task I want or need to advance, I should own the responsibility for advancing it.

There are lines that can’t be crossed. If I’m waiting for an expense approval for my latest business trip, I can’t just approve my own expenses to keep it moving. If advancing a certain task involves significant amounts of coding, I really shouldn’t do that because it’s not what I’m here for (and I wouldn’t expect an engineer to do, say, hiring manager interviews - that’s not what the engineer is here for). And so forth. But roughly speaking, if the next thing that needs to happen is well within my remit and abilities, why don’t I do it?

This idea is, essentially, the same as what's usually named internal open source (or a variation thereon). If I’m in charge of delivering some outcome, I should pretty darn well be on top of that progress, and be ready to do what’s necessary. Within boundaries, but those shouldn’t be too narrow.

The internal open source model is essentially all about collaborating to manage and resolve dependencies. Again, collaboration and dependencies: these are the two key things. The mechanisms explained in the iOSS V2MOM apply to the context of software engineering. Abstracting away from that context, the key idea is really to empower dependents to be proactive partners in a collaboration instead of increasingly impatient recipients of a service.

That’s it, that’s the thing.

(Note: The iOSS V2MOM was originally written by several folks at eBay. While I was driving that effort, the credit isn't all mine. Sadly, I do not recall the names of many individuals who contributed at the time, but hat tip to Mitch!)

Tags: work

Interpreted or Compiled?

2024-09-15 — Michael Haupt

What would you say: is Java an interpreted or a compiled language? What about C, C++, Python, Smalltalk, JavaScript, APL?

Laurie Tratt has written two (1, 2) absolutely wonderful (read: scientifically and technically nerdy) blog posts about the matter. He uses the Brainfuck programming language (it is less NSFW than the name suggests, but I will continue to use its name in abbreviated form, i.e., “bf”) and a series of implementations thereof that increasingly blur the boundary between interpreted and compiled.

The blog posts resonate with me especially because I use bf myself whenever I want to learn a new programming language: I just write an interpreter (or compiler?) for bf in that language.

These are two rather entertaining reads, and they will leave the reader in a better shape for the next inevitable discussion of whether this or that language is interpreted or compiled.

Tags: hacking, the-nerdy-bit

Hitting Rock Bottom in Personal Work Management

2024-09-14 — Michael Haupt

Some time ago, there was a point where I hit rock bottom. Workload got so high that single-focus work was just no longer possible. “Workload” here means the amount of WIP (work in progress) or things “going on in parallel” that simply cannot be said “no” to or delegated. I went through the thinking and solution described below. (At least I still had the time to reflect and come up with this.)

So, what to do in such a kind of situation?

There are a few techniques that can help but are a bit lacking in the specifics.

  • The “churn mode” from the Personal Kanban book suggests to simply line up all tasks, treat them as equally important, and just go from task to task, applying the concrete next possible step, before moving on to the next. This takes place in a round-robin fashion, until so many of the tasks have been completed that a more normal mode of operation can resume.

  • In the “1-3-5” method, originally, one chooses a single big, three medium-sized, and five small tasks to complete; this happens on a daily basis. A variation of the method I’m more familiar with, that also honours the existence of priority, is to pick, every day, one item that must be done, three that should be done, and five that can be done. Items in the should and can category can then be selected for promotion to the next higher category in case they didn’t get enough attention to be completed.

These two methods are nice enough, however, as hinted, they have some shortcomings:

  • Churn mode implies that everything is equally important and can be addressed by cyclically iterating. This doesn’t work when deadlines are involved, and when some things are really, really more important than others.

  • The 1-3-5 method assumes that there is really only one thing every day that must be done, which ignores the lamentable fact that several things do indeed, often enough, have to be completed by the same date.

  • Both methods have a slight neglect for the circumstance that there are calendars, with meetings in them, which often are about WIP as well. In other words, iterating in round-robin style doesn’t work when the order of meetings doesn’t match the order of tasks; and there are inevitably equally many must-do items as there are meetings about different work items in a day.

Here’s a way I’m dealing with that, which combines the two methods and adds a bit more. I’m using a Kanban board for visualisation, with an “in progress” column that is full of WIP. I now structure this column as follows:

  • There are five areas in the column, labelled “calendar”, “must do”, “should do”, “can do”, “others”, in this order.

  • On each day, I move everything that the calendar says needs attention today to the calendar area. Typically, I represent meetings here by the work items they are meant to advance. Another kind of work item is a scheduled item, which I’ll get to below.

  • The must do, should do, and can do areas I fill with 1, 3, and 5 items, respectively, as described above. These can’t be items already found the calendar area (no duplication please), but rather items I intend to do in the ample “working alone” focus time.

  • The others area has all the other WIP items.

Now, as soon as I have processed (but not yet finished) one item, I move it to the bottom (!) of the others area. That way, the least recently processed WIP items are at the top of that area, forming an annoying but nice round-robin backlog.

If there is a specific date on which I mean to continue processing a WIP item, I give it a due date, and move it to a dedicated column next to the in progress one named scheduled. These are the aforementioned scheduled items, which I will move back to the calendar area on the right day. There can be all kinds of reasons for scheduling an item: next meeting in a series, a deliver-by date I set for someone I need input from, or whatever.

First thing in the morning, I fill the areas of the in progress column as described above, and typically pull WIP items from the top of the others area, unless there are priorities that dictate otherwise. However, promoting WIP items from should and can to the next higher area helps with that rather well.

This Kanban board can be organised in a more horizontal way by using classes of service and swimlanes, of course. The tool in use limits the possibilities - I made this concept up using plain Trello.

All in all, this structure helped me get through that rough patch pretty well, not losing sight of anything. Afterwards, going back to the "normal" structure felt quite good. Now, should I find myself in a similar situation again, I have a tool ready.

Tags: work