Played some games, boosted some toots, tweaked some code⦠now itās time for bed.
Years ago, I used Kate, no, not somebodyās wife, but the KDE Advanced Text Editor, to export source code files and fragments into HTML with syntax highlighting. I think thatās where I got the initial <b> idea from. There were also bucketloads of <span style='color:#644a9b;'> all over the place, even inside <b>. No CSS classes defined upfront, all colors inlined. The final rendering in the browser looked great, but the source code ugly as hell in my opinion. However, Iām thankful for hinting me at <b>. I think this kicked off everything. :-)
@movq@www.uninformativ.de Itās the āLyse types the entire HTML by handā generator. Yes, no kidding. I write articles so rarely, that I can do that once in a while. Itās fun to some degree, but also not.
After some time, I finally recorded some Vim macros to insert <b>ā¦</b>, <var>ā¦</var>, <span class=s>ā¦</span> etc. around the tokens. This helped a little bit. But I was still questioning my mental state doing it like that. I also had to fix a bunch of the end tags by hand, because the word movement wasnāt enough or the end movement went too far. Quite the annoying process for sure.
But I think the HTML looks a wee bit nicer and is maybe even semantically a little bit better than having only <span>s everywhere. I find the <span class="whatever"> just soo awfully long. Of course, I never look at the code again, but knowing, that e.g. there is a <b> and it saves so many bytes in comparison, makes me happy. It is a more elegant solution in my opinion. Not by much, but better nonetheless. Itās a matter of simplicity. Admittedly, even I canāt avoid the <span>s alltogether. Oh well. On the other hand, Iām sure that this does not make any difference whatsoever. I bet, nobody and nothing, like a screenreader, analyzes the HTML for that, where this would be truly useful.
Oh! Maybe text browsers, though. It just occurred to me while composing this reply. :-) Haha, I lost my bet quickly. w3m picks up at least the <b> for keywords and builtin types, <u> for filenames and <i> for comments. Yey. No different styles for <var> and <mark>, unfortunately. elinks only renders the bold. Itās cool that I had the right intuition right from the beginning, despite being unable to pinpoint it. :-)
All the <span> hell with common syntax highlighters is a downer for me that keeps me from looking more into them. If I wrote more articles, I might rig something up with Pygments. At least thatās somehow positively connotated in my brain. Not sure if it actually deserves it, but I dealt with that in some loose form (canāt even remember) years and years ago. Apparently, it wasnāt too terrible.
To prepare the table of contents, I used grep and sed with some manual intervention in the end. The entire process can be improved. Absolutely.
You wrote your own site generator, didnāt you?
<updated> of the feed, too. But for some reason, some articles were suddenly marked as new.
@lyse@lyse.isobeef.org By the way, which site generator are you using? I kind of miss having code blocks with syntax highlighting and that generic yellow highlighting thing is pretty cool, too.
<updated> of the feed, too. But for some reason, some articles were suddenly marked as new.
@lyse@lyse.isobeef.org Oh, nice. That was quite the ride. :-) And all that because of locales. š³
But, did I understand that correctly? All Atom feeds were broken, right? Because they all use that same code path with that strftime/strptime dance in it?
Itās one of the reasons in fact Iāve been working on bob so I have a very concrete and strong foundation for how these things work, how they behave and how bad or good they can be. I am on-purpose building bob to be not only a decent coding tool and general task completion tool, but with serious security boundaries, sanitation, auditing and compliance. If Iām going to succeed at building autoonmous agents that can cope with a wider array of varying inputs (mostly natural language, some structural language) then it needs to be both a) Safe and b) Robust
And every time I ask it to do the same thing, it produces basically the same result. It will sometimes not produce a go.mod, but thatās probably because doing so isnāt as statically high as writing the code to sum numbers from stdin.
Which it does so in seconds, faster than I can type. The code is correct, it compiles and does exactly what I wanted. And the code looks pretty reasonable. It handles flotas, has error handling and handles space or line separated numbers on stdin.
@movq@www.uninformativ.de I think your points are pretty clear to me, thatās fine. Iām just seeing if you can perhaps see things a different way maybe?š¤ I would challenge the assertion that you cannot understand how Claude Code generated an output; which I can demonstrate easily with a fairly trivial example by the input:
Write a program in Go that sums a list of numbers from stdin and prints the result.
@prologic@twtxt.net Yeah, itās hard to get my point across here. I tried to address that a few paragraphs down.
Yes, I can tinker with AI techniques on a general level. Thatās cool but not really my area of interest.
What I certainly canāt do is learn how specific AI products work. I canāt possibly find out why Claude Code produced that particular line of code. Claude is just a magic box that does something and I have to trust it.
@bender@twtxt.net Now thatās an interesting philosophical viewpoint right there. But this assumes that the āAIā we seemingly have available to us today is actually telligent, understands and has cognitive reasoning. It does not. All of these LLM models from big-tech companies like Anthropic, OpenAI, Google, Microsoft, Meta and Alibaba are all just very powerful, very large multidimensional neural networks with attention that are very good at statistical probabilities of āwhat comes nextā. I think we get really upset over the wrong things sometimes. We need to continue to be upset that these 𤬠companies have basically destroyed any meaningful value of the concept of Copyright and Intellectual Property and Works of art. The so-called āAIā we have today is just a tool. Can you say for certain that the typewriter and the computer ruined our ability to write? Perhaps yes, but we still learn how to do so, likewise, I still think that learning to write code, research, read and write are all valuable skills to learn. Later on once you have the basics, you can defer some of the ātediousā work to these models, because frankly, theyāre far better at inferencing and pattern matching than you or i will ever be, not because theyāre better at pattern-matching per se, but because they have been trained on a very large corpus and they are much much faster at doing the same basic things we are far superior at.
Is it the fact that ābig techā companies have basically stolen all of human knowledge to their benefit to build these AI(s) thatās the problem? Or is it that these AI(s) can write code better than you can (some of the time)? Or is it that because of all of the above, thereās no joy left in writing code anymore? š¤
@lyse@lyse.isobeef.org Thanks! There are a few points in there that Iāll add to my list.
Your very first point is obviously crucial. āWriting codeā is just the means to an end for many people and they donāt really care about it or like it, so they love AI. I had this in another draft (it refers to the other list I posted):
https://movq.de/v/614f14c3ef/ramble.txt
And this right here is so important:
simplicity is the real art and much harder to achieve.
Finding an elegant, simple solution is waaaaaaaaaaaaaaaaaay harder than anything else. And hereās the thing: I donāt get why nerds/techies donāt get ānerd-snipedā by this. A lot of people love building big stuff and then brag about being clever/competent because they were able to build that big thing ā but once you realize that this approach is the lazy one, shouldnāt you make finding the elegant solution your goal? Doesnāt that give you more bragging rights?
(Am I being clear? Do you understand what I mean? š )
noai.html page. Apart from the global updated field in my feeds (that one got changed), everything else should be stable, though.
@movq@www.uninformativ.de Thanks. I noticed the <updated> of the feed, too. But for some reason, some articles were suddenly marked as new.
On some YouTube feed <entry>s, I noticed updated <updated> fields showing todayās timestamps. But unless there is no <published>, the <updated> is not even considered. I verified that in the source code. Yet, all the affected articles in Newsboat show todayās timestamp, not the years old publication timestamp. I generate the YouTube feeds from the original feeds myself once a day, so I doubt that this is cause by some YouTube shenanigans.
Very weird, it doesnāt make any sense at all. What is going on here? O_o It doesnāt appear that I have duplicates in the database either.
Itās official now: People are vomiting AI code into a repo that Iām supposed to maintain. At the same time, I donāt have the authority to decline those PRs.
RIP.
@tftp@tilde.town Ah, I see. I have a feeling that a lot of stuff is going on under the hood all the time and itās mostly the userland-visible things that stay the same? š¤ But yeah, some stuff is really, really old, like the TCP code Iāve recently (tried to) read.
Ah, thereās even a term for it:
https://en.wikipedia.org/wiki/Generation_effect
The generation effect is a psychological phenomenon whereby information is better remembered if it is generated from oneās own mind rather than simply read.
hfgl with your coding agents
So, itās plenty good enough for them.
Yeah, but on the other hand, you canāt even log in normally to a Matrix/Element account. I mean using username + password. Itās not expected that you ever log out or lose your browser session. If you do, you must use a one-time backup code (that you must create and save beforehand) to log in again.
To be fair, I canāt say that I fully understand what Matrix is doing in the first place. The text that I quoted reads like they have your keys. But they also claim that they only store this stuff encryped: https://element.io/en/help#encryption5 So ⦠encrypted with what? Only option here is my password, isnāt it? (But if my password was good enough to reclaim an account ⦠why do all the other stuff ā¦)
Matrix takes end-to-end encryption seriously. When I ran a Matrix server for the family, the family members would regularly lose their keys, because they didnāt pay attention to something. Thatās on purpose! Or rather, that was on purpose. Maybe itās different these days?
No clue.
Iām not always on the same page as Rob Pike, but this hit close to home:
Although trained in physics, I worked in the computing industry with pride and purpose for over 40 years. And now I can do nothing but sit back and watch it destroy itself for no valid reason beyond hubris (if Iām being charitable).
Ineffable sadness watching something I once loved deliberately lose its soul.
I spent my time trying to make it better. Not just write code, but find better or at least different ways to do so. Simpler, cleaner, more general, more comprehensible.
Whatās happening today is a complete repudiation of everything I was trying to achieve.
āSimpler, cleaner, more general, more comprehensibleā, thatās what Iāve been trying to establish in our teams as well. Obviously not to the same degree, but you get the idea.
And it all goes out the window now. Weāre doing the complete opposite ā and with full force.
Iām still having some fundamental design issues with my TUI widget system, so Iām still not comfortable making this code public.
But after a day of work (and discussing AI ad nauseam at work), I just donāt have any energy left. š
@movq@www.uninformativ.de LOL. I think I get the idea. I am concerned about AI too. Managers starting with āI donāt know anything about this, but here is what saysā. Infuriating.
I came across this one today, here is a gift link: https://www.nytimes.com/2026/04/15/opinion/art-artificial-intelligence.html?unlocked_article_code=1.bFA.XNiu.ZukFfdNl3Al1&smid=nytcore-ios-share
@movq@www.uninformativ.de I couldnāt agree more! I also have the feeling that it causes more people to just accept āitās a software problem, thereās nothing that can be done about itā. Which is very frightning to me.
Up until now, I was successful in refusing to actively use that crap. I had to do one mandatory AI training, but even our hippest AI enthusiasts found it absolutely terrible. Probably also nailed together by the same rubbish they want us to now use everyday as much as possible.
Code reviews are the part that I have to deal with most. And I believe that the code quality is degrading.
Letās hope the bubble bursts sooner than later. It will definitely burst at some point. Thatās for sure.
@falsifian@www.falsifian.org Thanks for clarification. I already thought something along those lines. Wow, so, you can really mix different encodings in a single file, crazy. My Perl experience is limited to maybe 10, 20 or at the very most 30 written lines of code over the decades.
@rdlmda@rdlmda.me In case youāre into terminal clients, you might like tt. We finally managed to abolished our GitLab instance, so I would need to make the code available to the public differently.
yhe sourde code is available so you can inspect it š
twtxt-lib, a new isomorphic TypeScript library for parsing and interacting with twtxt.txt files. Check out the demo at https://twtxt-lib.itsericwoodward.com/!
@prologic@twtxt.net soā¦
An isomorphic TypeScript library is a codebase, written in TypeScript, that can run in multiple JavaScript environments, most commonly both the web browser (client-side) and a server (like Node.js). The core idea is to share the exact same code across the frontend and backend, avoiding duplication and improving efficiency.
Hmmm, thatās a pity. I never realized that before. The following Go code
var b bool
ā¦
b |= otherBool
results in a compilation error:
invalid operation: operator | not defined on b (variable of type bool)
I cannot use || for assignments as in ||= according to https://go.dev/ref/spec#Assignment_statements. Instead, I have to write b = b || otherBool like a barbarian. Oh well, probably doesnāt happen all that often, given that I only now run into this after all those many years.
yes, yes thatās right. Mu (µ) now has a built-in LSP server for fans of VS Code / VSCodium š
You just go install ./cmd/mu-lsp/... and install the VS extension and hey presto š„³ You get outlines of any Mu source, Find References and Go to Definition!
https://github.com/unix-v4-commentary/unix-v4-source-commentary
A comprehensive, line-by-line commentary on the UNIX Fourth Edition source code (released November 1973; tape recovered from June 1974 distribution).
./bin/mu -B -o ... -p muos/amd64 ... target.
@prologic@twtxt.net Iād love to take a look at the code. š
Iām kind of curious to know how much Assembly I need vs. How much of a microkernel can I build purely in Mu (µ)? š¤
Canāt really answer that, because I only made a working kernel for 16-bit real mode yet. That is 99% C, though, only syscall entry points are Assembly. (The OpenWatcom compiler provides C wrappers for triggering software interrupts, which makes things easier.)
But in long mode? No idea yet. š At least changing the page tables will require a tiny little bit of Assembly.
Took me nearly all week (in my spare time), but Mu (µ) finally officially support linux/amd64 š„³ I completely refactored the native code backend and borrowed a lot of the structure from another project called wazero (the zero dependency Go WASM runtime/compiler). This is amazing stuff because now Mu (µ) runs in more places natively, as well as running everywhere Go runs via the bytecode VM interpreter š¤
Iām trying to implement configurable key bindings in tt. Boy, is parsing the key names into tcell.EventKeys a horrible thing. This type consists of three information:
- maybe a predefined compound key sequence, like Ctrl+A
- maybe some modifiers, such as Shift, Ctrl, etc.
- maybe a rune if neither modifiers are present nor a predefined compound key exists
Itās hardcoded usage results in code like this:
func (t *TreeView[T]) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
switch event.Key() {
case tcell.KeyUp:
t.moveUp()
case tcell.KeyDown:
t.moveDown()
case tcell.KeyHome:
t.moveTop()
case tcell.KeyEnd:
t.moveBottom()
case tcell.KeyCtrlE:
t.moveScrollOffsetDown()
case tcell.KeyCtrlY:
t.moveScrollOffsetUp()
case tcell.KeyTab, tcell.KeyBacktab:
if t.finished != nil {
t.finished(event.Key())
}
case tcell.KeyRune:
if event.Modifiers() == tcell.ModNone {
switch event.Rune() {
case 'k':
t.moveUp()
case 'j':
t.moveDown()
case 'g':
t.moveTop()
case 'G':
t.moveBottom()
}
}
}
})
}
This data structure is just awful to handle and especially initialize in my opinion. Some compound tcell.Keys are mapped to human-readable names in tcell.KeyNames. However, these names always use - to join modifiers, e.g. resulting in Ctrl-A, whereas tcell.EventKey.Name() produces +-delimited strings, e.g. Ctrl+A. Gnaarf, why this asymmetry!? O_o
I just checked k9s and theyāre extending tcell.KeyNames with their own tcell.Key definitions like crazy: https://github.com/derailed/k9s/blob/master/internal/ui/key.go Then, they convert an original tcell.EventKey to tcell.Key: https://github.com/derailed/k9s/blob/b53f3091ca2d9ab963913b0d5e59376aea3f3e51/internal/ui/app.go#L287 This must be used when actually handling keyboard input: https://github.com/derailed/k9s/blob/e55083ba271eed6fc4014674890f70c5ed6c70e0/internal/ui/tree.go#L101
This seems to be much nicer to use. However, I fear this will break eventually. And itās more fragile in general, because itās rather easy to forget the conversion or one can get confused whether a certain key at hand is now an original tcell.Key coming from the library or an āextendedā one.
I will see if I can find some other programs that provide configurable tcell key bindings.
Since I used so much Rust during the holidays, I got totally used to rustfmt. I now use similar tools for Python (black and isort).
What have I been doing all these years?! I never want to format code manually again. š¤£š
Vacation: Doing crazy things like C on DOS, lots of Rust, bare-metal assembly code, everything is fine.
Back at work: How the fuck do I move an email in this web mail program? Am I stupid? š®āšØ
I came across this on āWhy Is SQLite Coded In Cā, which I found interesting:
āThere has lately been a lot of interest in āsafeā programming languages like Rust or Go in which it is impossible, or is at least difficult, to make common programming errors like memory leaks or array overruns.ā
If thatās true, then encountering those issues means the programmer is, simply, horrible?
Spent most of the long weekend working on a few coding projects⦠specifically, I pushed some updates for TwtKpr to my test instance before spending some time working on the build process and demo page for my new twtxt-parsing library⦠which lead me to make some changes to my existing fluent-dom-esm library.
So, nothing actually got finished, but the incremental updates continueā¦
fib(35) doesn't regress too badly as I continue to evolve the language.
@lyse@lyse.isobeef.org Itās actually not nearly as half bad as I really thought it would be. Just having to eventually deal with the ālowering downā to machine code / ARM64 assembly in the end once youāve verified the semantics in the VM.
println("Hello World"):
@lyse@lyse.isobeef.org A āHello Worldā binary is ~372KB in size. I currently have peephole optimization and deac code optimizations in play, and a few other performance related ones, but nothing too fancy. I have a test case that ensures fib(35) doesnāt regress too badly as I continue to evolve the language.
Opinion / Question timeā¦
Do you think Mu (µ)ās native compiler and therefore emitted machine code āruntimeā (which obviously adds a bit of weight to the resulting binary, and runtime overheads) needs to support āruntime stack tracesā, or would it be enough to only support that in the bytecode VM interpreter for debuggability / quick feedback loops and instead just rely on flat (no stacktraces) errors in natively built compiled executables?
So in effect:
Stack Traces:
- Bytecode VM Interpreter: ā
- Native Code Executables: ā
Nice! š Here are the startup latencies for the simplest Mu (µ) program. println("Hello World"):
- Interpreter: ~5ms
- Native Code: ~1.5ms
@shinyoukai@neko.laidback.moe We finally abandoned our GitLab. I publicly mirrored my code in the Mills Data Center a few days ago: https://git.mills.io/lyse/tt2
@movq@www.uninformativ.de Well, just a very limited subset thereof:
- inline and multiline code blocks using single/double/triple backticks (but no code blocks with just indentation)
- markdown links using using
[text](url)
- markdown media links using

And thatās it. No bold, italics, lists, quotes, headlines, etc.
Just like mentions, plain URLs, markdown links and markdown media URLs are highlighted and available in the URLs View. Theyāre also colored differently, similarly to code segments.
I definitely should write some documentation and provide screenshots.
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.
https://lyse.isobeef.org/tmp/tt-bugfix-empty-lines-in-multiline-code-blocks.png
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! :-)