Earlier quoted context omitted.
TypeScript is good as a language. You can't generate static binaries out of it (except Docker images) and that itself is a deal breaker.
You can’t? I haven’t used it, but what’s wrong with “deno compile?” https://docs.deno.com/runtime/reference/cli/compile/
A Rust shaped hole
201–210 of 319 posts
Re: A Rust shaped hole
#202Earlier quoted context omitted.
> although that is very rarely done in practice. That's one difference. And the other important differences are: - Rust apps can depend on library "headers" written in other editions. That's the whole deal with editions! Breaking changes are local to your own code and don't fracture the ecosystem. - Rust has a built-in tool that automatically migrates your code to the next edition while preserving its behavior. In C+…
Not really, because the crates they depend on cannot expose APIs with semantic changes across versions. Also it requires everything to be compiled with the same compiler, from source code. There are tools available in some C++ compilers for migration like clang, note the difference between ISO languages with multiple implementations, and one driven by its reference compiler.
Not sure what you're talking about. Any specific examples?
> Also it requires everything to be compiled with the same compiler, from source code.
It's not related to editions at all. It's related to not having an implicit stable ABI.
It's possible have a dynamic Rust library that exposes a repr(C) interface, compile it into an .so using one version of the compiler, and then compile the dependent "pure Rust" crates using another compiler that's just going to read the metadata ("headers") of that library and link the final binary together. Same as in C and C++. You just can't compile any Rust code into a stable dynamic library, by defalut. (You can still always compile into a dylib that needs a specific compiler version)
Re: A Rust shaped hole
#203Earlier quoted context omitted.
> such programs are often more, not less, sensitive to OS changes. You may be technically correct that they are more sensitive to the kernel interface changes. But the point is that native, static binaries depend only on the kernel interface, while the other programs also depend on the language runtime that's installed on that OS. Typical Python programs even depend on the libraries being installed separately (in sou…
Even C has a runtime, even if tiny one.
Re: A Rust shaped hole
#204It is a bit unclear to me why somebody who rejects C++ because "I once spent an entire year in the heaven of C++, walking around in a glorious daze of std::vector and RAII, before one day snapping out of it and realizing that I was just spawning complexity that is unrelated to the problem at hand." (which I can absolutely agree with!) is picking Rust from all options. If there is a language that can rival C++ in term…
It's really not even remotely the same. C++ has literally >50 pages of specification on the topic of initialising values . All of these are inconsistent, not subject to any overarching or unifying rule, and you have to keep it all in mind to not run into bugs or problematic performance. Rust is a dead simple language in comparison.
Rust doesn’t have a standard, it has a book, so you should refer to the initialization section from Stroustrup’s C++ book to keep things fair.
Re: A Rust shaped hole
#205I think that of all those options, Typescript and Zig feel closest related. Zig has that same 'lightness' when writing code as Typescript and the syntax is actually close enough that a Typescript syntax highlighter mostly works fine for Zig too ;)
Re: A Rust shaped hole
#206Earlier quoted context omitted.
Rust is unreadable by default
Syntax could be less terse and abbreviated, I agree. But it's not unreadable. On the other hand some complain that Rust sometimes is too verbose, so I guess it's some balance.
That's just because you got used to it ;) (same as with modern C++ really, if you've used C++ long enough you become blind to its problems)
Re: A Rust shaped hole
#207Earlier quoted context omitted.
Even C has a runtime, even if tiny one.
I meant a runtime that has to be installed separately. It's possible to statically link a C runtime if you use musl, for example
A language runtime remains one, independently on how it was linked into the binary.
A language runtime are the set of operations that support the language semantics, which in C's case are everything that happens before main(), threading support (since C11), floating point emulation (if needed), execution hooks for running code before and after main(), delayed linking, and possibly more, depending on the compiler specific extensions.
Re: A Rust shaped hole
#208Earlier quoted context omitted.
You’re right that Rust is a ball of complication. I am a fan of Rust but it’s definitely a terse language. However there are definitely signs that they have thought about making it as readable as possible (by omitting implicit things unless they’re overwritten, like lifetimes). I’m reminded also about a passage in a programming book I once read about “the right level of abstraction”. The best level of abstraction is…
I do not really agree with respect to C. I often have to deal with C code written by unexperienced programmers. It is always relatively easy to refactor it step by step. For C++ this is much more painful because all the tools invented to make the code look concise make it extremely hard to follow and change. From the feature set, I would say that Rust is the same (but I have no experience refactoring Rust code).
Refactoring Rust projects is clearly the easiest because the compiler and type system ensure the program is correct at least in terms of memory access and shared resource access. It doesn't protect me from memory leaks and logical errors. But since Rust has a built-in testing framework, it's quite easy to prepare tests for logical errors before refactoring.
C/C++ refactoring is a nightmare - especially in older projects without modern smart pointers. Every change in ownership or object lifetime is a potential disaster. In multi-threaded applications it's even worse - race conditions and use-after-free bugs only manifest at runtime, often only in production. You have to rely on external tools like Valgrind or AddressSanitizer.
Python has the opposite problem - too much flexibility. You can refactor an entire class, run tests, everything passes, but then in production you discover that some code was dynamically accessing an attribute you renamed. Type hints help, but they're not enforced at runtime.
Rust forces you to solve all these problems at compile time. When you change a lifetime or ownership, the compiler tells you exactly where you need to fix it. This is especially noticeable in async code - in C++ you can easily create a dangling reference to a stack variable that an async function uses. In Rust, it simply won't compile.
The only thing where Rust lags a bit is compilation speed during large refactors. But that's a small price to pay for the certainty that your code is memory-safe.
Another area where Rust absolutely excels is when using AI agents like Claude Code. It seems to me that LLMs can work excellently with Rust programs, and thanks to the support of the type system and compiler, you can get to functional code quickly. For example, Claude Code can analyze Rust programs very well and generate documentation and tests.
I think Rust with an AI agent has the following advantages:
Explicit contract - the type system enforces clear function interfaces. The AI agent knows exactly what a function expects and what it returns.
Compiler as collaborator - when AI generates code with an error, it gets a specific error message with the exact location and often a suggested solution. This creates an efficient feedback loop.
Ownership is explicit - AI doesn't have to guess who owns data and how long it lives. In C++ you often need to know project conventions ("here we return a raw pointer, but the caller must not deallocate it").
Fewer implicit assumptions - in Python, AI can generate code that works for specific input but fails on another type. Rust catches these cases at compile time.
Re: A Rust shaped hole
#209Earlier quoted context omitted.
The C++ 11 move semantic is definitely an example of C++ programmers being sold a "pig in a poke"† The claim in the proposal document was that although this isn't the "destructive move" which programmers wanted (and which Rust had by 2015), the C++ 11 move feature can be realised with less disruption and is just as good. In reality it left significant performance on the table and you can't get it back without signifi…
Copy by default is the right way to go. Even if less performant, it’s safe and super-easy to understand. Let the people that want to squeeze the last drop of performance worry about moves… Move by default is the thing which complicates Rust so much.
Re: A Rust shaped hole
#210Earlier quoted context omitted.
Because they’re both complicated languages, but for different reasons. Rust didn’t really solve memory safety, it just pushed all the complexity into the type system. If one was struggling with memory errors in C++ that’s nice. If one was using Java, that still sucks. Furthermore some programmers really like complicated languages like Rust, Haskell, etc others like straightforward languages like Go, Python, etc.
Go is "straightforward" at the cost of making your codebase not straightforward: https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-... . Programming is complex. That complexity has to live somewhere. Python is absolutely not straighforward, it's a huge language with many moving parts and gotchas. Although, I admit, both are very easy to start programming in and to start shipping broken projects that appear…
Yes, Golang and Python and Java are very easy to start programming in. And unless we’re dealing with some really complex problem, like next-gen cryptocurrencies ;), by the time the Rust teams have gotten their code working and nice and proper as any Rust code needs to be, the Golang/Python/Java teams have already released to customers.
If one wants to be super-cautios and move accordingly slower to be really really sure they have no memory errors then that’s fine. There’s a market for that stuff. But selling this approach as a general solution is disingenuous.