consider me optimist now, but just few months ago, even frontier models were dumb, doing stupid mistakes all the time, all of them were so dumb I'd never expect anything to change in just few months.
601 karma · joined May 29, 2017
consider me optimist now, but just few months ago, even frontier models were dumb, doing stupid mistakes all the time, all of them were so dumb I'd never expect anything to change in just few months.
BTW: cheers, we should grab a beer some day :)
BTW: It was already discussed many times in rustc repo, and it's clear that there's no serious downside for apps, but no action was taken. I am sharing this in a hope to make some peer pressure...
I've been also very skeptical about Rust in the past, and all my points still hold (traits vs. accidental complexity, no introspection, barely usable macros, borrow checker awkward to use with arenas, orphan rule) but what's changed is that I won't be writing any of that myself, and LLMs are good in generating all sorts of glue and they are incredibly good at figuring out what's wrong, they just never get tired. so lots of Zig benefits are simply not relevant IMO.
one extra thing - Zig doesn't have interfaces, we often use comptime duck-typing and it works great, until it doesn't. it's not common but when you hit such case, it really sucks. I've realized that during my `serde` rabbit-hole and I had to revert the whole feature and scratch it. it was not obvious to me when I started but it's now clear to me that Rust really is higher-level PL than Zig. another example is Zig IO, I think it's screaming for interfaces, yet Zig is trying to pull all sorts of awkward hacks just to avoid it. it's sort of like when Go was avoiding generics but we all knew it's inevitable.
my current theory about Rust is that it might be bearable for my sorts of projects, given specific code guidelines. sort of like people writing C-style C++.
That said, I've been re-evaluating my choices lately.
Also, Clojure specifically is mem-safe because of the host VM and concurrency saf(ish) thanks to persistent data structures and core.async. It might be somewhere between 3 and 4, maybe together with Elixir. Unfortunately I never had enough time to play with it but I definitely will.
1. JS is mem-safe, single-threaded, and there are lots of training data. Easily my first choice. I'd put Python here as well, although I don't like it personally. Both should be used with "avoid external deps" in your AGENTS.md
2. Go might be a good second choice. Simple language, IMO good primitives for concurrency, well-designed std, therefore smaller potential for supply chain attacks.
3. Elixir/Erlang, little training data but rising. Safe language, safe concurrency, immutable, scalable, there are some many advantages... It has been avoided because it's different but that could change drastically in the age of LLMs.
4. Rust is probably next choice, along with C++, because while Rust is safer, the language is quite complex. C might be here too, there is a lot of training data, but every project is different and the language is very unsafe.
5. Zig, I really like the language, but it is terrible for LLMs, mainly because it's constantly changing, and the std is also under-featured and IMO weirdly designed. It's a fun language for hobby hacking, which I believe is not going anywhere, it's just not going to be something you will be payed for.
- Rust is huge, many options, many programming styles
- typical Rust project has lots of transitive dependencies
- there is nothing in Rust that disallows using system libraries or linking to them
- it's not even true that the program is going to be mem-safe because there could still be unsafe {} either in the repo, or in any of the transitive deps. not to say that safety is broader than just mem-safety.
if you think "written in Rust" says anything, I'd argue that you might give it a try and find out yourself. I did that, and I am glad I am out. the reason why I am telling you is because I've been click-baited (into Rust) before, and it took me few years to realize all of this, and to make a move.
I've been programming in Rust for 5 years and I could barely understand the code in their repo. Not because it was somehow advanced but because it didn't make any sense. It felt like that with every decision they could make, they always chose the hardest way.
On the other hand, I have never done any C++ (besides few tutorials) in my life and yet I found both Serenity/Ladybird and also WebKit to be very readable and understandable.
BTW: If anyone wants to reply that Rust is different then yes, of course it is - but that's the point, if there is a language that maps nicely to your problem domain, it's also very fast, and well-understood then why the hell you'd use a language that is well-known to NOT map to OOP?
And it makes a lot of sense, the pre-training is not perfect, it's just the best of what we can do today and the actual meaning leaks through different tokens. Then, QKV lets you rebuild the meaning from user-provided tokens, so if you know which words to use, you can totally change the behavior of your so-far benign LLM.
There was also paper about sleeper agents and I am by no way a doomer but the LLM security is greatly underestimated, and the prompt injection (which is impossible to solve with current generation of LLMs) is just the tip of the iceberg. I am really scared of what hackers will be able to do tomorrow and that we are handing them our keys willingly.
But from (let's say) El Capitan, I am always postponing upgrades, and recently I've been only upgrading by buying a new machine every 2 ys (except this year, I had to upgrade because of Metal, but I'm still one version below, still scared to upgrade to Tahoe). Every new feature they add to their OS I'm just disabling, every time I upgrade. Either I am not their customer anymore, or they are more and more clueless.
And it's not that hard, I just want it to work so that I can focus on my own stuff.
Sadly, accidental complexity is a common theme among react devs, not just ui libs, but also react-router, redux, redux-form, even tanstack useQuery() is way over-engineered and the core idea can be implemented in <50 lines and then you own the code and can make project-specific changes.
Maybe that's the biggest issue after all, people being lazy, expecting to do npm install and being able to reuse everything in any situation. Except that it almost never work like that and a lot of damage is done in the name of it... </rant>
For example, here's comptime dependency-injection container, which notably, can be configured and extended, completely in comptime, and the final glue is something which in theory the compiler could optimize away too (no idea if it does). https://github.com/cztomsik/tokamak/blob/main/src/container....
And regarding what they discuss in article, I did something similar for N-API, note how much you can do in few hundred lines, and I'd say that you can use it for most of what people do with napi-rs except that napi-rs is huge (and also unsafe, because it allows indirect recursion, which allows breaking all the rustc promises) https://github.com/cztomsik/napigen/blob/main/src/napigen.zi...
And it might be also something with GC, because I suppose the big boys are doing some GRPO over synthetically generated/altered source code (I would!) but obviously doing that in C++ is much more challenging - and I'd expect Rust to be straight impossible.
The tasks where it works great are things I'd expect to be part of dataset (github, blog posts), or they are "classic" LM tasks (understand + copy-paste/patch). The actual intelligence, in my opinion, is still very limited. So while it's true it's not "just recall" it still might be "mostly recall".
BTW: Copy-paste is something which works great in any attention-based model. On the other hand, models like RWKV usually fail and are not suited for this IMHO (but I think they have much better potential for the AGI)