Hurray, I finally fixed another rendering bug in tt that was bugging me for a long time. Previously, when there were empty lines in a markdown multiline code block, the background color of the code block had not been used for the empty lines. So, this then looked as if there were actually several code blocks instead of a single one.

mu (µ) now has builtin code formatting and linting tools, making µ far more useful and useable as a general purpose programming language. Mu now includes:
- An interpreter for quick āscriptinogā
- A native code compiler for building native executables (Darwin / macOS only for now)
- A builtin set of developer tools, currently: fmt (-fmt), check (-check) and test (-test).
I just fixed another bug in tt where the language hint in multiline markdown code blocks had not been stripped before rendering. It just looked like it was part of the actual code, which was ugly. I now throw it away. Actually, itās already extracted into the data model for possible future syntax highlighting.
os.UserConfigDir() up until a few seconds ago! I always implemented that myself.
@shinyoukai@neko.laidback.moe Yeah, they donāt truly support XDG. In fact, I looked in the Go stdlib source code to notice all the differences and shortcomings.
$HOME is not specified it tries to resolve the user's home directory by user.Current().HomeDir. Maybe that's overkill, I have to check the XDG spec.
Ok, the standard library implementation is wonky at best, at least in regards to XDG, because it really doesnāt implement it properly. https://github.com/golang/go/issues/62382 I stick to my own code then. It doesnāt properly support anything else than Linux or Unixes that use XDG, but personally, I donāt care about them anyway. And the cross-platform situation is a giant mess. Unsurprisingly.
@movq@www.uninformativ.de Thanks! Iāll have a look at SnipMate. Currently, Iām (mis)using the abbreviation mechanism to expand a code snippet inplace, e.g.
autocmd FileType go inoreab <buffer> testfunc func Test(t *testing.T) {<CR>}<ESC>k0wwi
or this monstrosity:
autocmd FileType go inoreab <buffer> tabletest for _, tt := range []struct {<CR> name string<CR><CR><BS>}{<CR> {<CR> name: "",<CR><BS>},<CR><BS>} {<CR> t.Run(tt.name, func(t *testing.T) {<CR><CR>})<CR><BS>}<ESC>9ki<TAB>
But this of course has the disadvantage that I still have to remove the last space or tab to trigger the expansion by hand again. Itās a bit annoying, but better than typing it out by hand.
@lyse@lyse.isobeef.org I can tell you this right now, writing assembly / machine code is fucking hard work⢠š Iām sure @movq@www.uninformativ.de can affirm 𤣠And when it all goes to shit⢠(which it does often), man is debugging fucking hard as hell! Without debug symbols I canāt use the regular tools like lldb or gdb š
@prologic@twtxt.net Yeah, the parser part is what I typically enjoy. Havenāt really looked into code generation itself.
Iām currently looking at your µ commits from the last few days. Holy cow! :-)
Whoo! I fixed one of the hardest bugs in mu (µ) I think Iāve had to figure out. Took me several days in fact to figure it out. The basic problem was, println(1, 2) was bring printed as 1 2 in the bytecode VM and 1 nil when natively compiled to machine code on macOS. In the end it turned out the machine code being generated / emitted meant that the list pointers for the rest... of the variadic arguments was being slot into a register that was being clobbered by the mu_retain and mu_release calls and effectively getting freed up on first use by the RC (reference counting) garbage collector š¤¦āāļø
@shinyoukai@neko.laidback.moe Nah itās more like thereās a lot of repeated code, because when you go from source language to intermediate representation to machine code, well you just end up writing a lot of the same patterns over and over again. I need to dedupe this I think.
The compiler technique Iām using here is to not āemitā most of the runtime if itās actually never used in your program, and also dropping dead code in the SSA pass.
Hmmm I need to figure out a way to reduce the no. of lines of code / complexity of the ARM64 native code emitter for mu (µ). Itās insane really, itās a whopping ~6k SLOC, the next biggest source file is the compiler at only ~800 SLOC š¤
@movq@www.uninformativ.de I think I can get binaries even smaller with a bit more work and effort š¤ But yeah still working on the native code generation (at least for macOS targets)
@movq@www.uninformativ.de Oh thatās fine, Mu can compile to native code and so far binaries. at least on macOS are in the order of Kb in size š
My little toy operating system from last year runs in 16-bit Real Mode (like DOS). Since Iāve recently figured out how to switch to 64-bit Long Mode right after BIOS boot, I now have a little program that performs this switch on my toy OS. It will load and run any x86-64 program, assuming itās freestanding, a flat binary, and small enough (< 128 KiB code, only uses the first 2 MiB of memory).
Here Iām running a little C program (compiled using normal GCC, no Watcom trickery):
https://movq.de/v/b27ced6dcb/los86%2D64.mp4

Next steps could include:
- Use Rust instead of C for that 64-bit program?
- Provide interrupt service routines. (At the moment, it just keeps interrupts disabled.)
@prologic@twtxt.net You write so much code ⦠itās incredible. š
@movq@www.uninformativ.de @kiwu@twtxt.net it just so happens to be a happy coincidence that Iām extending muās capabilities to now include a native toolchain-free compiler (doesnāt rely on any external gcc/clang or linkers, etc) that lowers the mu source code into an intermediate representation / IR (what @movq@www.uninformativ.de refers to as āthick layers of abstractionsāā¦) and finally to SSA + ARM64 + Mach-O encoder to produce native binary executables (at least for me on my Mac, Linux may some later?) š¤£
Got a nice conspiracy theory for you:
https://mastodon.social/@mcc/115670290552252848
Actually wait I just thought about this and realized that the precise timing of the ACTUAL GitHub seed bank, by which I mean the Arctic Code Vault, on 2020-02-02, makes it more or less a perfect snapshot of pre-Copilot GitHub. Also precisely timed before we all got brain damage from COVID. This is the only remaining archive of source code by people with a fully working sense of smell
(Bonus points because the Arctic World Archive is located in Svaldbard and thatās the name of the AI in Stacey Kadeās āCold Eternityā.)
I cleaned up all my of AoC (Advent of Code) 2025 solutions, refactored many of the utilities I had to write as reusable libraries, re-tested Day 1 (but nothing else). here it is if youāre curious! This is written in mu, my own language I built as a self-hosted minimal compiler/vm with very few types and builtins.
I finished all 12 days of Advent of Code 2025! #AdventOfCode https://adventofcode.com ā did it in my own language, mu (Go/Python-ish, dynamic, int/bool/string, no floats/bitwise). Found a VM bug, fixed it, and the self-hosted mu compiler/VM (written in mu, host in Go) carried me through. š„³
I just completed āPrinting Departmentā - Day 4 - Advent of Code 2025 #AdventOfCode https://adventofcode.com/2025/day/4 ā Again, Iām doing this in mu, a Go(ish) / Python(ish) dynamic langugage that I had to design and build first which has very few builtins and only a handful of types (ints, no flots). š¤£
I just completed āLobbyā - Day 3 - Advent of Code 2025 #AdventOfCode https://adventofcode.com/2025/day/3 ā Again, Iām doing this in mu, a Go(ish) / Python(ish) dynamic langugage that I had to design and build first which has very few builtins and only a handful of types (ints, no flots). š¤£
I just completed āGift Shopā - Day 2 - Advent of Code 2025 #AdventOfCode https://adventofcode.com/2025/day/2 ā But again, Iām solving this in my own language mu that I had to build first š¤£
I just completed āSecret Entranceā - Day 1 - Advent of Code 2025 #AdventOfCode https://adventofcode.com/2025/day/1 ā However I did it in my own toy programming language called mu, which I had to build first š¤£
Alright, Advent of Code is over:
https://www.uninformativ.de/blog/postings/2025-12-12/0/POSTING-en.html
Itās been quite the time sink, especially with the DOS games on top, but it was fun. š„³
In case youāre wondering: All puzzles (except for part 2 of day 10) were doable in Python 1 on SuSE Linux 6.4 and ran in a finite time on the Pentium 133. Puzzle 10/2 might have been doable as well if I had better education. š¤£
my MIND is a MACHINE that turns ILLEGIBLE CODE into ILLEGIBLE CODE

iāve learned a lot of lessons from writing my notes app, gonna apply this to bbycll and refactor the code to make it way more legible cause my custom templating system is only kind of a giant mess
@prologic@twtxt.net Here you go:
(LTT = āLinus Tech Tipsā, thatās the host.)
LTT: There was a recent thing from a major tech company, where developers were asked to say how many lines of code they wrote ā and if it wasnāt enough, they were terminated. And there was someone here that was extremely upset about that approach to measuring productivity, becauseā
Torvalds: Oh yeah, no, you shouldnāt even be upset. At that point, thatās just incompetence. Anybody who thinks thatās a valid metric is too stupid to work at a tech company.
LTT: You do know who you just said that about, right?
Torvalds: No.
LTT: Oh. Uh, he was a prominent figure in the, uh, improved efficiency of the US government recently.
Torvalds: Oh. Apparently I was spot on.
@lyse@lyse.isobeef.org My theory is that these people simply donāt do ācode archeologyā. When something breaks, they donāt reach for git log. They simply donāt experience the pain that comes with bad commits / commit messages.
Or is that different in your company? š
@movq@www.uninformativ.de Same. :ā-( I just donāt get how people do code archeology with all their shit messages and huge commits changing a gazillion of different things. I always try to lead by setting good examples, but nofuckingbody is picking up on that. At all. Even when bringing this up every now and then.
@itsericwoodward@itsericwoodward.com Nice to see someone else also participating! š„³
(Btw, they donāt want us to share our inputs: https://www.reddit.com/r/adventofcode/wiki/faqs/copyright/inputs/ Yeah, itās a bit annoying. I also have to do quite a bit of filtering on my repo ā¦)
Most of the Advent of Code action happens on the Fediverse, Iām afraid:
https://tilde.zone/@movq/115595022987289988
Thereās just way more people over there who participate. š„“
Working on day 3 of the Advent of Code 2025: https://adventofcode.com/
My solutions repo: https://git.itsericwoodward.com/eric/aoc-2025
@prologic@twtxt.net Using your own language?! Thatās really nice! I hope you get home soon so you can give the code a try. š
I actually canāt progress to day two till I get home 𤣠ā I havenāt pushed the code for the mu compiler yet š¤¦āāļø So no-one can check my work even if they were so kind š¤£
completely untested as i have no remote way of running mu code from Vietnam š¤£
Thinking about doing Advent of Code in my own tiny language mu this year.
mu is:
- Dynamically typed
- Lexically scoped with closures
- Has a Go-like curly-brace syntax
- Built around lists, maps, and first-class functions
Key syntax:
- Functions use
fnand braces:
fn add(a, b) {
return a + b
}
- Variables use
:=for declaration and=for assignment:
x := 10
x = x + 1
- Control flow includes
if/elseandwhile:
if x > 5 {
println("big")
} else {
println("small")
}
while x < 10 {
x = x + 1
}
- Lists and maps:
nums := [1, 2, 3]
nums[1] = 42
ages := {"alice": 30, "bob": 25}
ages["bob"] = ages["bob"] + 1
Supported types:
int
bool
string
list
map
fn
nil
mu feels like a tiny little Go-ish, Python-ish language ā curious to see how far I can get with it for Advent of Code this year. š
Advent of Code 2025 starts tomorrow. š„³š
This year, Iām going to use Python 1 on SuSE Linux 6.4, writing the code on my trusty old Pentium 133 with its 64 MB of RAM. No idea if that old version of Python will be fast enough for later puzzles. Weāll see.

@movq@www.uninformativ.de I see problems with that, yes. Case in point:

@prologic@twtxt.net AI is slot machines for coders:
- āBefore starting tasks, developers forecast that allowing AI will reduce completion time by 24%. After completing the study, developers estimate that allowing AI reduced completion time by 20%. Surprisingly, we find that allowing AI actually increases completion time by 19%āAI tooling slowed developers down.ā https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/
- āStack Overflow data reveals the hidden productivity tax of āalmost rightā AI codeā: https://venturebeat.com/ai/stack-overflow-data-reveals-the-hidden-productivity-tax-of-almost-right-ai-code
The same intermittent reward operant conditioning that gets people addicted to gambling and thinking that if they follow certain rituals theyāll win ānext timeā drives peopleās beliefs that AI tools are making them more productive when theyāre making them less productive. Iām going to guess that a side effect of this is that people think theyāre typing less when in the longer term theyāre typing the same amount or more when you factor in the productivity loss (as far as Iāve read the studies donāt measure this so Iām only guessing).
People are also being rapidly de-skilled by this technology: the more they use it, the more their actual skills atrophy. āContinuous exposure to AI might reduce the ADR (adesoma detection rate) of standard non-AI assisted colonoscopy, suggesting a negative effect on endoscopist behaviour.ā (science speak for saying that radiologists get worse at seeing tumors in scans once theyāve used AI): https://www.thelancet.com/journals/langas/article/PIIS2468-1253(25)00133-5/abstract
Nobody who cares about the future should be using this stuff for anything.
since there are quite literally no note taking apps that work for me, iāve began writing my own! to get started real quick i adapted the core part of bbycllās backend and it works so nicely ā which speaks volumes to the quality of the code! should really break it out into a custom framework. iām also realizing how easy it would be to get bbycll v1 readyā¦but this is probably more important since itāll allow me to get my life in order ^^ā
@bender@twtxt.net Once Advent of Code starts, Iāll start spamming, donāt worry. š
All my newly added test cases failed, that movq thankfully provided in https://git.mills.io/yarnsocial/twtxt.dev/pulls/28#issuecomment-20801 for the draft of the twt hash v2 extension. The first error was easy to see in the diff. The hashes were way too long. Youāve already guessed it, I had cut the hash from the twelfth character towards the end instead of taking the first twelve characters: hash[12:] instead of hash[:12].
After fixing this rookie mistake, the tests still all failed. Hmmm. Did I still cut the wrong twelve characters? :-? I even checked the Go reference implementation in the document itself. But it read basically the same as mine. Strange, what the heck is going on here?
Turns out that my vim replacements to transform the Python code into Go code butchered all the URLs. ;-) The order of operations matters. I first replaced the equals with colons for the subtest struct fields and then wanted to transform the RFC 3339 timestamp strings to time.Date(ā¦) calls. So, I replaced the colons in the time with commas and spaces. Hence, my URLs then also all read https, //example.com/twtxt.txt.
But that was it. All test green. \o/
I just noticed this pattern:
uninformativ.de 201.218.xxx.xxx - - [22/Nov/2025:06:53:27 +0100] "GET /projects/lariza/multipass/xiate/padme/gophcatch HTTP/1.1" 301 0 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
www.uninformativ.de 103.10.xxx.xxx - - [22/Nov/2025:06:53:28 +0100] "GET http://uninformativ.de/projects/lariza/multipass/xiate/padme/gophcatch HTTP/1.1" 400 0 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
Let me add some spaces to make it more clear:
uninformativ.de 201.218.xxx.xxx - - [22/Nov/2025:06:53:27 +0100] "GET /projects/lariza/multipass/xiate/padme/gophcatch HTTP/1.1" 301 0 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
www.uninformativ.de 103.10.xxx.xxx - - [22/Nov/2025:06:53:28 +0100] "GET http://uninformativ.de/projects/lariza/multipass/xiate/padme/gophcatch HTTP/1.1" 400 0 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
Some IP (from Brazil) requests some (non-existing, completely broken) URL from my webserver. But they use the hostname uninformativ.de, so they get redirected to www.uninformativ.de.
In the next step, just a second later, some other IP (from Nepal) issues an HTTP proxy request for the same URL.
Clearly, someone has no idea how HTTP redirects work. And clearly, theyāre running their broken code on some kind of botnet all over the world.
I was looking at some ancient code and then thought: Hmm, maybe it would be a good idea to see more details in this error message. Which of the values donāt line up. On the other hand, that feature isnāt probably used anyway, because itās a bit ugly to use (historically evolved). And on top of that, most teams need something slightly different, if they deal with that sort of thing.
I still told my workmates about it, so they could also have a look at it and we can decide tomorrow what to do about it. Speaking of the devil, no kidding, not even half an hour later, a puzzled tester contacted me. She received exactly that rather useless error message. Looks like I had an afflatus. ;-)
Itās interesting, though, that in all those years, nobody stumbled across this before. At least we now know for sure that this is not dead code. :-)
@movq@www.uninformativ.de I think I now remember having similar problems back then. Iām pretty sure I typically consulted the Qt C++ documentation and only very rarely looked at the Python one. It was easy enough to translate the C++ code to Python.
Yeah, the GIL can be problematic at times. Iām glad it wasnāt an issue for my application.
For those curious, the new Twtxt <-> ActivityPub bridge Iām building (bidirectional) simply requires three things:
- You register your Twtxt feed to the bridge: https://bridge.twtxt.net
- You verify that you in fact own/control the feed by putting the verification code somewhere on/in your feed (doesnāt matter where or how)
- You proxy/forward requests for
/.well-known/webfingerto the Bridgebridge.twtxt.net.
Iām still testing through and ironing out bugs š Please be patient! š
technically I can put the Bridge verificaiton code in my feedās metadata so no-one really ever sees or notices it š¤ Maybe Iāll add a first-class button/field thingy in yarnd so users can āregister their feedā straight from their pod? š¤
@lyse@lyse.isobeef.org Yeah, I noticed that too. I havenāt double-checked my code, though. Maybe it has something to do with selecting the correct URL? I mean, these feeds donāt have any # url = fields, so maybe thatās it?
tilde.club feeds have no # nick and is messing with yarnd's behavior š
@bender@twtxt.net Just wrote better code with tests š¤£