Readit News logoReadit News
Expurple · 7 months ago
> If someone posts a patch or submits a PR to a codebase written in C, it is easier to review than any other mainstream language. There is no spooky at a distance. [..] Changes are local.

Lol, wut? What about about race conditions, null pointers indirectly propagated into functions that don't expect null, aliased pointers indirectly propagated into `restrict` functions, and the other non-local UB causes? Sadly, C's explicit control flow isn't enough to actually enable local reasoning in the way that Rust (and some other functional languages) do.

I agree that Go is decent at this. But it's still not perfect, due to "downcast from interface{}", implicit nullability, and similar fragile runtime business.

I largely agree with the rest of the post! Although Rust enables better local reasoning, it definitely has more complexity and a steeper learning curve. I don't need its manual memory management most of the time, either.

Related post about a "higer-level Rust" with less memory management: https://without.boats/blog/notes-on-a-smaller-rust/

atoav · 7 months ago
I program both C/C++ and Rust (the latter to a lesser degree currently). Rust is far superior to C in Error locality, if you write ideomatic Rust. Most of the types of errors I make in C would have been cought at compile time in Rust.

Aside from Rusts ownership model you can use the type system to enforce certain things. A typical example is that Rust uses different String types to force programmers to deal with the pitfalls. Turns out if you have a file name in an operating system it could not be a valid string, or you could have valid Unicode text that could not be a filename. Rust having different types for OS Strings and internal Unicode means when you want to go from one to the other you need to explicitly deal with the errors or choose a strategy how to handle them.

Now you could totally implement strings within Rust in a way that wouldn't force that conversion and programmers would then yolo their way through any conversion, provided they even knew about the issue. And the resulting error would not necessarily surface where it orginated. But that would be programming Rust like C.

In my experience many C libraries will just happily gulp up any input of any remotly valid shape as if it was valid data without many devs being even aware there were cases or conversions they would have had to deal with. You recognize exceptionally good C devs by the way they avoid those pitfalls.

And these skilled C devs are like seasoned mountaineers, they watch their every step carefully. But that doesn't mean the steep north face of the mountain is the safest, fastest or most ergonomic way to get to the summit. And if you believe that C is that, you should be nowhere near that language.

amluto · 7 months ago
Even ignoring undefined behavior and nulls, everything in C is mutable. Action at a distance is basically the norm.
BiteCode_dev · 7 months ago
And global states.

I remember the first time I was using gettext and wonder "wait, why do I have to switch the language for my whole program if I need it for just this request?" and realized that's because GNU gettext was made like that.

pjmlp · 7 months ago
The C myth keeps being perpetuated, sadly.

And had not GNU/FSF made C the official main language for FOSS software on their manifesto, by the time when C++ was already the main userspace language across Windows, OS/2, Mac OS, BeOS, that "It is the reason for C's endurance" would be much less than it already is nowadays, where it is mostly UNIX/POSIX, embedded and some OS ABIs.

Xunjin · 7 months ago
It's funny because that was the main argument against Rust when I introduced it at the company I worked for before, but the tool has been widely used internally ever since. Because made it easy to understand the locality PRs and how it solved most safety issues (they still need some unsafe usage).
whytevuhuni · 7 months ago
If anything I'd like an even lower-level Rust.

There's so many good high-level languages to choose from, but when you need to go low-level, there's essentially only C, C++, Rust. Maybe Zig once it reaches 1.0.

What we need isn't Rust without the borrow checker. It's C with a borrow checker, and without all the usual footguns.

sealeck · 7 months ago
> What we need isn't Rust without the borrow checker. It's C with a borrow checker, and without all the usual footguns.

Which would look a lot like... Rust!

Expurple · 7 months ago
> There's so many good high-level languages to choose from

We have many popular high-level languages, but I disagree that they are good. Most of them are fragile piles of crap unsuitable for writing anything larger than a throwaway script.

(In my subjective and biased assessment, which is hovewer based on professional experience)

dxxvi · 7 months ago
> What we need isn't Rust without the borrow checker. It's C with a borrow checker, and without all the usual footguns

I agree with the other comment. Then what you need is Rust without all the bells and whistles (pattern matching, Cow, Rc, Result, Option ...).

rahkiin · 7 months ago
It would be an interesting excercise just to see how such a language would look.

Would modules be needed or can preprocessing work still. How more advanced will the type system need to be. And how will pointers chanhe to fix all footguns and allow static borrow checking.

buzzin__ · 7 months ago
"C is the language that combines raw power of assembly with expressiveness of assembly."
pjmlp · 7 months ago
Modula-2, Object Pascal, Ada,....

Zig is basically Modula-2 in C syntax clothing.

junebash · 7 months ago
That blog post is pretty close to describing Swift. :)
rowanG077 · 7 months ago
I was very surprised to read this too. Local reasoning is the antithesis of C.

Deleted Comment

shmerl · 7 months ago
Yeah, and C can get unreadable fast. Obfuscated C contest is a great example: https://www.ioccc.org

But that doesn't mean it's a good idea to use such style for PRs, lol.

Expurple · 7 months ago
That's a really weird example to give. You can write unreadable code in any language if you're determined enough
peppingdore · 7 months ago
Rust is unreadable by default
uecker · 7 months ago
It 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 terms of complexity, it is Rust.
tialaramex · 7 months ago
I've seen this idea from a few people and I don't get it at all.

Rust is certainly not the simplest language you'll run into, but C++ is incredibly baroque, they're not really comparable on this axis.

One difference which is already important and I think will grow only more important over time is that Rust's Editions give it permission to go back and fix things, so it does - where in C++ it's like venturing into a hoarder's home when you trip over things which are abandoned in favour of a newer shinier alternative.

rich_sasha · 7 months ago
C++'s complexity is coming from how eager it is to let you shoot yourself in the foot. Rust will make you sweat blood to prove the bird in the sky you're shooting at is really not your own foot.
pjmlp · 7 months ago
Because of the type system, with its ML influence, two macro systems, the stuff on nightly that many folks enjoy using, having to rely on external crates for proper error handling and async/await features.

Additionally, given its ML influence, too many people enjoy doing Haskell level FP programming in Rust, which puts off those not yet skilled in the FP arts.

Also the borrow checker is the Rust version of Haskell burrito blogs with monads, it is hard to get how to design with it in mind, and when one gets it, it isn't that easy to explain to others still trying to figure it out.

Hence why from the outside people get this opinion over Rust.

Naturally those of us with experience in compilers, type systems theory and such, see it differently, we are at another level of understanding.

viccis · 7 months ago
>where in C++ it's like venturing into a hoarder's home when you trip over things which are abandoned in favour of a newer shinier alternative

Perl is so bad about this that I once worked on a very old codebase in which I could tell approximately when it was written based on which features were being used.

blub · 7 months ago
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.

adastra22 · 7 months ago
C++ has editions too btw. C++11, C++14, C++17, etc. These are opt in and allowed to break compatibility, although that is very rarely done in practice.
dijit · 7 months ago
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 the one that cuts to the meat of your problem the quickest - spending a significant amount of time rebuilding the same abstractions over and over (which, is unfortunately often the case in C/C++) is not actually more simple, even if the language specifications themselves are simpler.

C codebases in particular, to me, are nearly inscrutable unless I spend a good amount of time unpicking the layers of abstractions that people need to write to make something functional.

I still agree that Rust is a complex language, but I think that largely just means it’s frontloading. a lot of the understanding about certain abstractions.

uecker · 7 months ago
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).
bryanlarsen · 7 months ago
Reading between the lines, the author is a Haskell fan. Haskell is another "complicated" language, but the complexity feels much different than the C++ complexity. Perhaps I would describe it as "complexity that improves expressiveness". If you like Haskell for its expressiveness but dislike C++ for it's complexity, I suspect Rust is a language you're going to like.
fn-mote · 7 months ago
My impression was the opposite. I wondered how well the author knew Haskell. They mention:

(1) The "intimidating syntax". Hey, you do not even need to be using <$> never mind the rest of those operators. Perl and Haskell can be baroque, but stay away from that part of the language until it is useful.

(2) "Changes are not localized". I'm not sure what this means. Haskell's use of functions is very similar to other languages. I would instead suggest referring to the difficulty of predicting the (time|space) complexity due to the default lazy evaluation.

FTA:

> In contrast, Haskell is not a simple language. The non-simplicity is at play both in the language itself, as evidenced by its intimidating syntax, but also in the source code artifacts written in it. Changes are not localized, the entire Haskell program is one whole — a giant equation that will spit out the answer you want, unlike a C program which is asked to plod there step by step.

Edited to make the critique more objective.

tines · 7 months ago
The two are incomparable in both quality and quantity. The complexity of Rust comes from the fact that it's solving complex problems. The complexity of C++ comes from a poorly thought out design and backwards-compatibility. (Not to slight the standards committee; they are smart people, and did the best with what they had.)

Anothere way of putting it is, if you didn't care about backwards-compatibility, you could greatly simplify C++ without losing anything. You can't say the same about Rust; the complexity of Rust is high-entropy, C++'s is low-entropy.

materielle · 7 months ago
The C++ standard committee is definitely smart. But language design requires sense beyond just being smart.

They didn’t do the best with what they had. Sure, some problems were caused by C backwards compatibility.

But so much of the complexity and silliness of the language was invented by the committee themselves.

uecker · 7 months ago
I would say that most of the complexity in both cases comes from overengineering.
andrepd · 7 months ago
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.

blub · 7 months ago
As the definition says, the C++ standard is a formal technical document.

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.

_mlbt · 7 months ago
Swift is a great C++ and Rust alternative that doesn’t get enough attention outside of Apple platforms. It’s a performant, statically typed, compiled language that feels almost like a scripting language to write code in. It’s memory safe, cross platform, has a fantastic standard library, and has excellent concurrency capabilities. Even the non-Xcode tooling is maturing rapidly.

The big weak spot really is lack of community outside of Apple platforms.

cosmic_cheese · 7 months ago
I would love to see a cross-platform desktop UI toolkit for Swift, preferably one that’s reactive and imperative-dominant with declaritivity sprinkled in where it makes sense (all-in declarative design like SwiftUI hits too many language weak points for the time being). Swift is really quite nice to write once you get a feel for it, and as long as one is judicious about advanced feature use, it looks more familiar and less intimidating than Rust does which is great for newcomers.
rapsey · 7 months ago
Swift has IMO surpassed Rust in complexity. Rust changes very little but Swift has gone through multiple major changes and is accumulating cruft.
shim__ · 7 months ago
Swift seems more like an Go or Python alternative
wisty · 7 months ago
I'm not at all fluent at Rust, but I think c++ is not just complex, but every c++ project is complete in a different way.
jcranmer · 7 months ago
Having developed a fair amount of expertise with both C++ and Rust, C++ is on a completely different level of complexity from Rust.

In Rust, for most users, the main source of complexity is struggling with the borrow checker, especially because you're likely to go through a phase where you're yelling at the borrow checker for complaining that your code violates lifetime rules when it clearly doesn't (only to work it out yourself and realize that, in fact, the compiler was right and you were wrong) [1]. Beyond this, the main issues I run into are Rust's auto-Deref seeming to kick in somewhat at random making me unsure of where I need to be explicit (but at least the error messages basically always tell you what the right answer is when you get it wrong) and to a much lesser degree issues around getting dyn traits working correctly.

By contrast C++ has just so much weird stuff. There's three or four subtly different kinds of initialization going on, and three or four subtly different kinds of type inference going on. You get things like `friend X;` and `friend class X;` having different meanings. Move semantics via rvalue references are clearly bolted on after the fact, and it's somewhat hard to reason about the right things to do. It has things like most-vexing parse. Understanding C++ better doesn't give you more confidence that things are correct; it gives you more trepidation as you know better how things can go awry.

[1] And the commonality of people going through this phase makes me skeptical of people who argue that you don't need the compiler bonking you on the head because the rules are easy to follow.

tialaramex · 7 months ago
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 significant further language change.

† This phrase would have been idiomatic many years ago but it is still used with the same intent today even though its meaning is no longer obvious, the idea is that a farmer at market told you this sack you can't see inside ("poke") has a piglet in it, so you purchase the item for a good price, but it turns out there was only a kitten in the bag, which (compared to the piglet) is worthless.

Deleted Comment

Aeolun · 7 months ago
Rust is a lot better at producing helpful error messages than any C++ I’ve seen.
Narew · 7 months ago
It's funny because I have completely the opposite stance. When I code in rust (mainly algorithm), I always struggle to change what I want to do to what rust allow me to do. And all this complexity has nothing to do with the problem.
jplusequalt · 7 months ago
>If there is a language that can rival C++ in terms of complexity

Fair, but this relative. C++ has 50 years of baggage it needs to support--and IMO the real complexity of C++ isn't the language, it's the ecosystem around it.

blu3h4t · 7 months ago
Why would everyone call rust a c+++ whet it is obviously an ocaml erlang hybrid :D
jplusequalt · 7 months ago
>There is an apocryphal story about Euler in elementary school solving all the math problems that the teacher gave to the class in a jiffy, so the teacher tells him to sum up the numbers to a thousand to get him to stop pestering for more. The expectation was that Euler would go through the numbers "imperatively", like C, summing them up. Instead, what Euler did was discover the summation formula and solved it "declaratively" like Haskell, in one go, as an equation.

I've heard this story be accounted to Gauss, not Euler.

n4r9 · 7 months ago
Yes, it's Gauss. In fact the technique is sometimes known as "Gaussian summation". The New Scientist has an article where the author chases down early references to the story: https://www.americanscientist.org/article/gausss-day-of-reck...

The earliest reference is a biography of Gauss published a year after his death by a professor at Gauss' own university (Gottingen). The professor claims that the story was "often related in old age with amusement and relish" by Gauss. However, it describes the problem simply as "the summing of an arithmetic series", without mention of specific numbers (like 1-100). Also, it was posed to the entire classroom - presumably as a way to keep them busy for a couple of hours - rather than as an attempt to humiliate a precocious individual.

lblume · 7 months ago
Yes. In Germany the formula n(n+1)/2 is actually called the Gaussian sum formula, or even the "small Gauss". [0]

[0] https://de.wikipedia.org/wiki/Gaußsche_Summenformel

tux3 · 7 months ago
>To paraphrase Norvig's Latency numbers a programmer should know, if we imagine a computer that executes 1 CPU instruction every second, it would take it days to read from RAM.

It's a detail, but this is a little bit off. RAM latency is roughly around ~100ns, CPUs average a couple instructions per cycle and a few cycles per ns.

Then in the analogy, a stall on RAM is about a 10 minute wait; not quite as bad as losing entire days.

jlokier · 7 months ago
In current machines, that's way off depending on how you choose to count "1 CPU instruction" for the metaphor.

Take Apple's latest laptops. They have 16 CPU cores, 12 of those clocking at 4.5 GHz and able to decode/dispath up to 10 instructions per cycle. 4 of those clocking at 2.6 GHz, I'm not sure about their decode/dispatch width but let's assume 10. Those decoder widths don't translate to that many instructions-per-cycle in practice, but let's roll with it because the order of magnitude is close enough.

If the instructions are just right, that's 824 instructions per nanosecond. Or, roughly a million times faster than the 6502 in the Apple-II! Computers really have got faster, and we haven't even counted all the cores yet.

Scaling those to one per second, a RAM fetch taking 100ns would scale to 82400 seconds, which 22.8 hours, just short of a day.

Fine, but we forgot about the 40 GPU cores and the 16 ANE cores! More instructions per ns!

Now we're definitely into "days".

For the purpose of the metaphor, perhaps we should also count the multiple lanes of each vector instruction on the CPU, and lanes on the GPU cores, as if thery were separate processing instructions.

One way to measure that, which seems fair and useful to me, is to look at TOPS instead - tera operations per second. How many floating-point calculations can the processor complex do per second? I wasn't able to find good figures for the Apple M4 Max as a whole, only the ANE component, for which 38 TOPS is claimed. For various reasons tt's reasonable to estimate the GPU is the same order of magnitude in TOPS on those chips.

If you count 38 TOPS as equivalent to "CPU instructions" in the metaphor, then scale those to 1 per second, a RAM fetch taking 100ns scales to a whopping 43.9 days on a current laptop!

tux3 · 7 months ago
If you're counting all instruction executing in parallel with the maximum on-paper IPC on all CPUs, accelerators, and GPUs, the number your get has no clear relation to RAM latency. It really is comparing apples and oranges.

This scenario where all your 16 cores are doing 10 instructions per clock assumes everything is running without waiting, at full instruction-level and CPU-level parallelism. It's a measure of the maximum paper throughput when you're not blocked waiting on memory.

You could compare that to the maximum throughput of the RAM and the memory subsystem, and that would give you meaningful numbers (for instance, how many bytes/cycle can my cores handle? How many GB/s can my whole system process?).

Trying to add up the combined throughput of everything you can on one side and the latency of a single fetch on the other side will give you a really big number, but as a metaphor it will be more confusing than anything.

renewiltord · 7 months ago
This seems like the classic 9 women making a baby in 1 month. Even if the CPU can execute 824 instructions per nanosecond, it can't execute 1 instruction in 1/824 nanoseconds. You can't mix throughput and latency like that.
tines · 7 months ago
Very cool, I wish the author good luck! I've been writing a compiler in Rust for a few months now and I absolutely love it. The ways it solves most of the problems it addresses feel like the "right" way to do things.

There are some things that feel a little weird, like the fact that often when you want a more complex data structure you end up putting everything in a flat array/map and using indices as pointers. But I think I've gotten used to them, and I've come up with a few tricks to make it better (like creating a separate integer type for each "pointer" type I use, so that I can't accidentally index an object array with the wrong kind of index).

Rust is one of those languages that change how you think, like Haskell or Lisp or Forth. It won't be easy, but it's worth it.

lenkite · 7 months ago
The best way to use Rust is to circumvent use of the borrow-checker and lifetimes and use indices everywhere! Suddenly, it becomes more pleasant and easy to refactor :).
genshii · 7 months ago
This hits close to home. TypeScript is also my language of choice for 90% of the software I write. I agree with the author that TypeScript is very close to the perfect level of abstraction, and I haven't seen another language with a type system that's nearly as enjoyable to use. Of course, TS (any by extension JS) obviously has its issues/complications. Bun solves a lot of the runtime-related issues/annoyances though.

For the other 10% software that is performance-sensitive or where I need to ship some binary, I haven't found a language that I'm "happy" with. Just like the author talks about, I basically bounce between Go and Rust depending on what it is. Go is too simple almost to a fault (give me type unions please). Rust is too expressive; I find myself debugging my knowledge of Rust rather than the program (also I think metaprogramming/macros are a mistake).

I think there's space in the programming language world for a slightly higher level Go-like language with more expressiveness.

daxfohl · 7 months ago
I'm surprised ocaml doesn't have more market share here. Native, fast, robust type system, GC, less special syntax than rust, less obtuse than Haskell.
pragmatic · 7 months ago
No libraries.

All the niche languages have a chicken and egg problem.

Only way around that is to be able to piggy back on C or JavaScript or Java.

lostmsu · 7 months ago
Until recently it did not have multithreading
ashishb · 7 months ago
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.
skybrian · 7 months ago
You can’t? I haven’t used it, but what’s wrong with “deno compile?”

https://docs.deno.com/runtime/reference/cli/compile/

genshii · 7 months ago
Yeah, that's definitely a huge drawback. Bun lets you get pretty close though with the `--compile` flag: https://bun.sh/docs/bundler

Too bad the binaries are 60MB at a minimum :(

wk_end · 7 months ago
I'd love to see someone develop a compiler for TypeScript that got, say, Ocaml-like performance. There's a bunch of reasons why that'd be tough though - you'd probably want a language very-similar-to-but-not-quite-like-TypeScript.
Tade0 · 7 months ago
I mean you can, they're just inappropriately large.
renewiltord · 7 months ago
I recently came to a production Typescript codebase and it took minutes to compile. Strangely, it could not behave correctly without a linter rule `no-floating-promises` but the linter also took minutes to lint the codebase. It was an astounding exercise in patience. Faster linters like oxlint exist but they don't have a notion of cross-file types so `no-floating-promises` is impossible on them.

The worst part is that `no-floating-promises` is strange. Without it, Knex (some ORM toolkit in this codebase) can crash (segfault equivalent) the entire runtime on a codebase that compiles. With it, Knex's query builders will fail the lint.

It was confusing. The type system was sophisticated enough that I could generate a CamelCaseToSnakeCase<T> type but somehow too weak to ensure object borrow semantics. Programmers on the codebase would frequently forget to use `await` on something causing a later hidden crash until I added the `no-floating-promises` lint, at which point they had to suppress it on all their query builders.

One could argue that they should just have been writing SQL queries and I did, but it didn't take. So the entire experience was fairly nightmarish.

WorldMaker · 7 months ago
Promise<T> is not T and Typescript's type system will catch that in most cases with a simple type assertion (add a type to the function return; add a `satisfies` check somewhere).

If it isn't catching it often enough, without a lot more extra type assertions, you may be missing a Typescript strict flag like noImplicitAny. (In general I find that I prefer the full `"strict": true` in the compilerOptions of tsconfig.json and always write for all strict checks.)

Also if your codebase is still relying on "explicit" `any`, try `unknown`.

Also, yeah Knex doesn't look like the best ORM for a Typescript codebase. Typescript support in Knex is clearly an after thought, and the documentation admits it:

> However it is to be noted that TypeScript support is currently best-effort.

mikojan · 7 months ago
You don't have to suppress it, you just write `void` in front of the floating promise.

Which is arguably the correct way to handle this situation anyway. It makes it unmistakably clear that you are intentionally throwing away a return value.

Sophistifunk · 7 months ago
I very much enjoy reading and writing TS code. What I don't enjoy is the npm ecosystem (and accompanying mindset), and what I can't stand is trying to configure the damn thing. I've been doing this since TSC was first released, and just the other day I wasted hours trying to make a simple ts-node command line program work with file-extension-free imports and no weird disagreements between the ts-node runner and the language server used by the editor.

And then gave up in disgust.

Look, I'm no genius, not by a long shot. But I am both competent and experienced. If I can't make these things work just by messing with it and googling around, it's too damned hard.

mrkeen · 7 months ago
I encountered this trying out PureScript. Looks like a good language, but I gave up after a couple of trips through npm, bower, yarn...
childintime · 7 months ago
Fully agree. Try bun.
lmm · 7 months ago
If they're serious about their criteria they should go with OCaml (or maybe, like, Swift, or any of dozens of languages in that space).

(Of course they actually do want Haskell but they probably need to get there gradually)

tayo42 · 7 months ago
Does ocaml have a mature ecosystem of libraries and dependencies? And easy way to manage them? Even rust with all its hype lacks in this area imo.
lmm · 7 months ago
No, and that's part of why I use Scala instead. But this person is looking to make a binary to do a small thing on their desktop and does not list dependency management among their criteria.

Deleted Comment

sealeck · 7 months ago
It doesn't have a great ecosystem of libraries, but it _does_ have a good way to manage them: https://dune.build/, which as I understand it was developed at Jane Street (lots of code and dependencies) and is now open source.

> Even rust with all its hype lacks in this area imo.

This is surprising to me! I find that Rust has pretty excellent tooling, and Cargo is substantially better than the package manager in most other languages...

myaccountonhn · 7 months ago
Depends on what you're doing and how you structure your program. It certainly does not match the ecosystem of Go, Rust or C++
zem · 7 months ago
right! the table at the end just screamed "use ocaml and be happy"
legobmw99 · 7 months ago
nobody gives OCaml a thought in these discussions. It’s such a wonderful language!
frou_dh · 7 months ago
It doesn't use curly-braces driven syntax, so will probably be accused of being "complex" and dismissed.
jimbokun · 7 months ago
Doesn't Rust steal a lot from Ocaml?
lmm · 7 months ago
Yes, but not garbage collection. Given that OP's main concern with Rust is not wanting to manually manage memory, they should really just use Ocaml.
steveklabnik · 7 months ago
Kinda sorta yeah. The original implantation was in OCaml, too.
nlitened · 7 months ago
> To paraphrase Norvig's Latency numbers a programmer should know, if we imagine a computer that executes 1 CPU instruction every second, it would take it _days_ to read from RAM.

I think the author probably misread the numbers. If CPU executed 1 instruction every second, it would take just 1—2 minutes to read from uncached RAM, no need to be overly dramatic.

Overall, this reads to me like a very young programmer trying to convince themselves to learn Rust because he heard it's cool, not an objective evaluation. And I'm totally on board with that, whatever convinces you, just learn new things!