Denis Defreyne

Weeknotes 2025 W37: Meat?!

September 8​–​14, 2025

Quick bits:

  • There’s a good chance that my fellow acting students and I will hold a performance mid-December. If we’re mutuals, let me know if you want to attend. Concrete plans to follow.

  • Trackballs are so funny. I like to keep things clean, but a trackball works better if it’s greasy. My trackball had rather stiff movement earlier, so I greased it up with [REDACTED] and it started working so much better.

  • My grocery lists continue to be written in three languages — Dutch, German, and English.

  • Charlie Kirk was a massive piece of shit.


Shower thoughts:

  • I technically have more years of experience with JavaScript than with English.

  • The difference between a Hashtag and a Warntag is that the former is silent and the latter is loud. Very loud.

  • The word “cybernetics” and “Kubernetes” share a Greek root. I might just start calling it Cybernetes from now on. Very cyber. Very 90s cool. See you in Kuberspace.


I ate meat! A Wolt order got mixed up, and I got someone else’s dinner delivered to me. It had bits of chicken in it. I could have thrown it away. I could’ve picked out the bits of meat. But that would have been a waste and not served any purpose, so I ate it all.

This is a pragmatic exception, and I have zero intent to give up my vegetarianism. Eating animals is wrong.


I’ve been working on Deng, a highly work-in-progress1 HTML-centric templating language with a Zig and C API. Templates in Deng would look like this:

<h2>Articles</h2>

{% for page.articles as article %}

<h3>{{ article.title }}</h3>

{% if article.author as author %}
<p>Written by {{ author }}.</p>
{% endif %}

<p>{{ article.content | excerpt(maxWords: 20) }}</p>

{% endfor %}

Most of Deng is not implemented yet. It’s all, erm, highly aspirational. The inspiration for Deng includes Nunjucks, Jinja and the Django template language.

It also has a Ruby API through ffi.2 To use it, first call Deng.compile to compile the template into bytecode:

bytecode = Deng.compile("Hello, {{ firstName }}!")

Then, evaluate the bytecode, providing a lookup function:

res = Deng.eval(bytecode) do |key|
  case key
  when "firstName"
    "Denis"
  else "lastName"
    "Defreyne"
  end
end

res now contains the string "Hello, Denis!". Neat.

Why bytecode? Well, this way, the heavy lifting of parsing the template only needs to be done once. Evaluating the template bytecode is faster than parsing the original template. This is helpful because evaluating the template (i.e. executing the bytecode) is done dozens or hundreds of times, while compilation is only needed once.3

This also explains why there is no bytecode for the TomatenMark implementation. Generating bytecode from TomatenMark isn’t worth it, because the bytecode would only be executed once.

The bytecode for Hello, {{ firstName }}! looks like this, in assembly-like representation:

WRITE "Hello, "
PUSH "firstName"
LOOKUP
POP_AND_WRITE
WRITE "!"
STOP

Or in bytes, with hexadecimal representation except for strings with I’ve kept as-is:

01 07 "Hello, "
03 09 "firstName"
05
04
01 01 "!"
00

The bytes at the start of the line are the opcodes. The second bytes (0x07, 0x09, and 0x01) are the bytesizes of the string arguments. The last instruction is 0x00, which ends bytecode execution.4

Converting the strings to hexadecimal bytes yields this as the hexadecimal representation of the bytecode:

01 07 48 65 6c 6c 6f 2c 20
03 09 66 69 72 73 74 4e 61 6d 65
05
04
01 01 21
00

Plenty of work is still pending for Deng. All of this, of course, contributes to the progress towards that new static-site generator that I’m writing.


Take-home coding challenges in job interviews still are a pain.

I recently failed such a coding challenge. This was in Ruby (a programming language that I know like the back of my hand) writing a backend service (which I have done countless times before).

After the rejection, I got the feedback that I did not complete the task; there were unfinished to-do items. This is true; I left those in the code because I didn’t get to them in the two-hour time limit.

This is frustrating. The purpose of a technical job interview is to assess the skill level of a candidate. An incomplete solution does not indicate a lack of skill, especially when the candidate5 leaves specific to-do items in the code.

I also find it frustrating when I, as a candidate, am supposed to fully independently create a complete solution during the interview process, when in reality, software engineering is a collaborative process (think code reviews and pair programming). Heck, most companies want their employees back in the office, arguing that on-site presence fosters collaboration.

When I fail a technical challenge in a programming language I’ve used for about 20 years, doing a task that I’ve been successfully doing for over a decade, then the failure genuinely is not mine but the interviewers’.

And yep, I am grumpy. This job search is dragging on, and setbacks like these are frustrating.


The job search is complicated by there being so many pure-AI companies — companies whose whole raison d’être is AI and just AI, without a having a clear and specific problem that they’re working to solve.

It’s distinctly reminiscent of the blockchain hype. Years ago, so many companies sprung up doing blockchain work without having a clear purpose beyond it being just blockchain. I don’t know how those companies are doing, but I sure know that extremely few of those companies — if they still exist — are still hiring. I predict that the same will happen with the pure-AI companies in the not-too-distant future.

There are also a handful of companies that are creating AI companion apps. I find this gross and unethical. I have the same opinion about AI psychotherapy apps, which are going to get people killed. I want no part in any of this.

Even though I am in the AI skeptics camp, I see value in AI-augmented products. I don’t mind the presence of AI, as long as it is not intrusive, and complements an existing product. In other words: a product with AI still needs to be sensible and useful without the AI.


Entertainment:

  • I finished All Systems Red,6 the first entry in the Murderbot Diaries series. It’s a bit bland. I am beginning to suspect that I am simply a grumpy reader.

  • I spent a ton of time in Norman’s Guy No Man’s Sky7 this week. It sure is a time sink. I’ve got two settlements up and running, and a nice corvette.


Links:


  1. Frankly, even the name is work in progress? “Deng?” What kind of name is that?! ↩︎

  2. Integrating Ruby with C libraries is enough of a pain that I’m putting the Ruby integration to the side for now. FFI is a pain, and mkmf (for building native extensions) is an abomination. ↩︎

  3. A limitation of Nanoc is that there is no way to precompile templates. My work-in-progress Zig static site generator should allow that. ↩︎

  4. At the same time, the 0x00 byte functions as the C string terminator. How neat. ↩︎

  5. The candidate is me. I am talking about myself in third person! Denis finds this strange. ↩︎

  6. Martha Wells, All Systems Red (New York: Tom Doherty Associates, 2017). ↩︎

  7. No Man’s Sky (Hello Games, 2016), published by Hello Games. ↩︎

You can reply to this weeknotes entry by email. I’d love to hear your thoughts!
If you like what I write, stick your email address below and subscribe. I send out my weeknotes every Sunday morning. Alternatively, subscribe to the web feed.