My internet provider in the early 90s maintained a Unix system with pine and lynx; it only allowed access to WWW a few months after we subscribed to their dial-up. I didn't know what to do with that remote system, but I knew `cd` and `ls`, so I looked around. Somewhere on the filesystem, I found a Hexen (IIRC) demo, and decided to download it via Kermit (the only tool/protocol I knew how to use). It took almost a day to finish, but in the end it ran - I was overjoyed. I somehow even found a cheat code for all weapons, and spent a few weeks playing the first 2 levels, while occasionally poking around in the remote system. Then the phone bill came - for 7x more than normal, on top of the ISP subscription - and I lost access to both the Internet and the computer for more than a month. Needless to say, I learned to watch that connection timer like a hawk, and it served me well for the next 10 years before broadband connection was available.
Interestingly, an almost identical proverb exists in Polish ("him" is replaced with "swine" canonically, but it's often replaced by a person's name). It's used to suggest that someone is either too dumb or too self-assured to accept criticism. Is the intended meaning similar in Greek?
What's funny is that with Sol, I added an instruction to AGENTS.md in one project to prefer sed/python ("deterministic tools" in general) for moving code instead of deleting it and rewriting it elsewhere from memory, because otherwise it butchered comments. After switching to Astra, I saw it suddenly do this for all edits in all projects, which isn't great: the second argument to `replace` is still written "from memory", but now you need to unravel the Python script before you can understand what was actually changed.
Yes, large. I haven't used Zig much myself, but from a few experiments I ran, Zig handles dead code elimination exceptionally well. It compiled a full Win32 GUI calc app that used Capy (a full, cross-platform GUI framework) into a 133kb executable. Removing Capy completely and using Win32 APIs directly produced an even smaller (93kb) binary (it also removed some DLL dependencies, leaving basically only ntdll.dll). For the same task, Rust + Slint produced a 4.7 MB binary that still depended on multiple (non-Windows-provided) shared libraries.
Given another commenter's mention of a similar project written in Nim that yielded a 1.6 MB binary, my first guess is that the 6 MB Zig binary simply isn't optimized for size - it might be a debug build. If not that, then I'm not sure what's happening, but yeah, in the context of Zig, 6mb for a CLI app is a bit strange.
Steam provides a stable Linux runtime, but it's not containerized or isolated Docker/Flatpak-style. It's closer to a chrooted env with some specific distro, but without chroot and the need to maintain said distro. They want to provide runtime stability and compatibility comparable to that on Windows - it's a great initiative, and I really hope they'll succeed. The snowflake-like userlands on Linux are a pain, but the current solutions (Docker, Flatpak, things like conda) are all bad solutions to this particular problem (though they are good solutions to other problems, so it's not a criticism, just a difference in goals).
However, Steam Runtime for Linux was still in beta, last I checked. Plus, it doesn't solve the cross-platform part. But for Linux-native development, Steam Runtime might be what's needed to have long-term compatibility for apps (finally).
It doesn't have to cost money. You can write a normal Windows app and run it under Proton. For end users, provided that they have Steam installed (it's free), they can just add "Non-Steam game" to the library - it's ~4 clicks.
It works. It works great. It's actually the only sensible solution if you want something compiled today to work without changes on both Windows and Linux in 10 years.
I did an experiment, implementing a GUI calculator, and Rust + Slint + cross-compiling to Windows (I develop on Linux) + Proton runtime was the clear winner:
- compiled bundle: 20 MB (F#/dotNet + Avalonia: 207 MB)
- loc: ~1000 (dotNet: ~700)
- dlls: none other than what Wine provides (dotNet: 67 .dll files)
You have an option to build for Linux for dev/testing, then you cross-compile to Windows and provide a short (4 points) instruction for adding the Windows build to Steam on Linux. It works, and it will most likely continue to work in the future, unless Valve folds and both Wine and Proton die. The only thing worth looking out for is crates that depend on external shared libraries: you need to bundle them manually. Other than that, it works.
Another option I considered was Zig with the Win32 API, but the LOC count was unacceptably high.
I'm working on a write-up for the experiment. The premise was: "I'm working on Linux and want to create a GUI app that will, with the build done today, continue working on Windows and Linux for the next 10 years". Steam/Proton + mostly static compilation + bundled libraries is the only solution that makes this mostly painless.
> It doesn't have to cost money. You can write a normal Windows app and run it under Proton. For end users, provided that they have Steam installed (it's free), they can just add "Non-Steam game" to the library - it's ~4 clicks.
I'm saying you don't need to publish on Steam to make your app run on Steam. You really don't. A user can add any executable to the Steam Library via the "Add a Game -> Add Non-Steam Game" button in the bottom-left corner of the GUI. It works 100% locally and with any kind of executable (not just games). It also bypasses any auto-updates. Finally, you can launch an app like that from the CLI or a desktop shortcut without opening Steam (well, it'll still run and update itself when needed, but you bypass the GUI).
> A user can add any executable to the Steam Library via the "Add a Game -> Add Non-Steam Game" button in the bottom-left corner of the GUI.
Yeah, but that's also not exactly a better user-experience for the end-user than "Download .exe, double-click to launch" or "Download .msi, finish install, run program".
Distribute your software however you want, I tend to try to make the download and install as familiar as possible to the users of the specific platforms.
Btw, even your starting prompt is guiding the model to just agree with your opening statement. You can't just roll with whatever the model says and assume the conclusion of "definitely can run in 10 years unchanged" is true.
Yeah, that's why the second prompt starts with "You misunderstood" and a correction. This is a long conversation, with multiple experiments performed and a lot of inspection of all the intermediate results on my end between prompts. You assuming otherwise without reading is a bit offensive.
To your point on installation: sure, but if you value it that much, just pay Valve to add you to the Steam store? And that would be the only possible solution given my constraints, all explicitly mentioned at least once in the linked conversation:
- binary produced today works
- without changes
- on both Linux and Windows
- is a GUI app
- has some dependencies
- is developed on Linux (no Windows needed)
For this set of constrains, Proton/Wine with a cross-compiled Win32 binary/bundle is literally the only solution (care to name another?)
For other constraints, it's a solution. Worth considering. That's all.
> You assuming otherwise without reading is a bit offensive.
Yeah sorry, hurling huge LLM conversations at me tends to make me skim them, hope you don't mind I didn't study the conversation you had with ChatGPT in detail.
That you considered someone skimming a chat log offensive yet the act of sharing those chat logs and expecting others to dredge through them, is almost offensive to me. So I guess we can call it even now.
> For this set of constrains, Proton/Wine with a cross-compiled Win32 binary/bundle is literally the only solution (care to name another?)
Cross-compiling the good old way, with a Linux VM, Windows VM and a macOS host (maybe Mac Mini?). I basically have the very same requirements (+ macOS), except zero third party dependencies, and end up doing it this way, all managed with Nix so basically all the installation-bloatyness is something I deal with so users get the exact same experience they expect on their OS.
Interesting to see Factor and J so far to the bottom and right in the zstd test, but much closer to the rest in the Pandoc test (with Asm taking their place). This suggests that both the task and language (not just the language) influence the efficiency.
I try to use LLMs for Kotlin, Python, Emacs Lisp, and Smalltalk (among many others, but these are what I have ongoing projects in). You'd think that Kotlin and Python would be much easier to generate than the other two, right? But that's not what I observed: Elisp is very close to Python in terms of how fast and how many tokens it takes to generate the code! The generated Elisp code is often better on the first try than generated Kotlin code for a comparable task.
Smalltalk is... complex. It's meant to be developed interactively in a running image, but running Codex on API pricing is too expensive, and Codex CLI cannot interact with the image without a lot of plumbing. I ended up building multiple tools that live in the image and a protocol for calling them, and a set of skills for using them - including code search, docs search, test runner, and script/string evaluator. I also defined a way of annotating types for method arguments and return values (without having a type checker), which helped a lot. Still, it's an uphill battle; I wouldn't go there on API pricing!
My takeaway is that it's not obvious which language fits the LLMs and a given task best.
It's not. The latest-and-greatest models on $200/mo subscriptions routinely produce bloated code full of boilerplate. They are incapable of producing elegant, concise, readable, correct-by-design code - they literally can't do it, even with the smallest samples, and it gets much worse as the scale of the implementation increases. You can't will the capability into them through prompts. You probably could do so with fine-tuning or other techniques, but I suspect that would just make the variance higher - and the average code quality would be much lower than it already is.
The code generated by LLMs is passable, but never truly good. The same is true for LLM-generated designs and architectures, just even more so. They are trained on all the code out there, and the percentage of really good code is so vanishingly small that it's incredibly hard to replicate even for humans after a lifetime of learning. LLMs would need to reach a next level of capability to consistently recognize good code. Generating it consistently is out of the question for at least the next few generations of the AI.
Not all code has to, or needs to, be good. LLM-generated code is useful and helpful. It's an incredible time-saver for one-off scripts, and you can make an LLM implement and maintain parts of the program you need, but don't care to make good at the moment. LLMs are very efficient (if we ignore externalities) and easy-to-use code generators, which is huge in itself. However, they are not great or even good at generating code.
Last weekend, there was a post showcasing a Rust library with utility functions for writing parsers. It featured a simple line-by-line INI file parser. I decided to rewrite it in Python with PyParsing, a library I happen to know well. GPT-5.6-Sol High wrote the grammar that worked. It was tragically bloated, poorly factored, and multiple grammar problems were masked by parse actions. It worked, but it was decidedly bad code. I then rewrote the grammar by hand, getting it down to 1/3 of the length, eliminating all parse actions, and improving error messages in the process. I then spent 2 hours trying to convince the model to perform the same refactorings I did, but had to give up: no matter what I tried, the model couldn't get all the needed changes to coexist at the same time. When it got the terseness right, it inevitably ruined error handling. When it got the grammar right, it ruined the factoring. And so on.
Later on, I decided to make the model rewrite the PyParsing grammar in Smalltalk's PetitParser - a pretty close match in terms of capabilities. I gave the model my version of the grammar. I told it to translate that Python code. It still butchered more than half of it, doing "optimizations" (the model's words) that replaced a cached production with a literal + 3 message sends in 8 places in the (trivial!) grammar. I explained what I value in the original code, why those are important features to keep, and tried again. It still couldn't give me an idiomatic Smalltalk translation, though it did get significantly closer. I concluded that the model has a very limited understanding of how concepts I wanted can manifest in actual code and called it a day.
To give you an idea of the scale: excluding blank lines and imports, the grammar is exactly 10 lines of Python...
So no - LLMs are not good at generating code. They are just fast and convenient, and again - that's huge. But it's nowhere near a level where it can be steered to produce good code - much less being able to generate good code by default.
(I realize this post is a bit off topic and it's just an anecdote - but I've experienced this daily for the past half a year; I'm not basing my opinion on just that last attempt.)
Yeah, definitely on point. I use AI for code generation, but I ride herd on it quite a lot and I limit scope viciously and with hard rules about what the models are even allowed to generate. It's worked out pretty well, but it's hardly the "oh send a question get a full system back" that people try to pretend it is.
It's not that bad... But it is bad. It looks cool, and I managed to read the first few paragraphs. But when the code scrolled into view, it stopped looking cool and became an eye-destroying disaster.
YMMV, but OP, if you read this, please consider disabling the text-shadow for code snippets... or disabling syntax highlighting in code snippets. These two things are not a good thing together.
reply