Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Yes, the secret of Rust is that it offers both a) some important but slightly subtle language features from the late '70s that were sadly not present in Algol '52 and are therefore missing from popular lineages b) a couple of party tricks, in particular the ability to outperform C on silly microbenchmarks; b) is what leads people to adopt it and a) is what makes it non-awful to program in. Yes it's a damning indictment of programming culture than people did not adopt pre-Rust ML-family languages, but it could be worse, they could be not adopting Rust either.




>important but slightly subtle language features from the late '70s

Programming-language researchers didn't start investigating linear (or affine) types till 1989. Without the constraint that vectors, boxes, strings, etc, are linear, Rust cannot deliver its memory-safety guarantees (unless Rust were radically changed to rely on a garbage collecting runtime).

>it's a damning indictment of programming culture than people did not adopt pre-Rust ML-family languages

In pre-Rust ML-family languages, it is harder to reason about CPU usage, memory usage and memory locality than it is in languages like C and Rust. One reason for that is the need in pre-Rust ML-family langs for a garbage collector.

In summary, there are good reasons ML, Haskell, etc, never got as popular as Rust.


> Programming-language researchers didn't start investigating linear (or affine) types till 1989.

Sure, but as ModernMech said, the vast majority of Rust's benefits come from having sum types and pattern matching.

> In pre-Rust ML-family languages, it is harder to reason about CPU usage, memory usage and memory locality than it is in languages like C and Rust.

Marginally harder for the first two and significantly harder for the last, sure. None of which is enough to matter in the overwhelming majority of cases where Rust is seeing use.


> Sure, but as ModernMech said, the vast majority of Rust's benefits come from having sum types and pattern matching.

Doubt. There were lots of languages giving you just that, and they never had this amount of hype. See Scala, OCaml, Haskell, etc.

Rust has one unique ability, and many shared by other languages. It's quite clearly popular for the former (though languages are a packages, so of course it's a well put together language all around).


> There were lots of languages giving you just that, and they never had this amount of hype. See Scala, OCaml, Haskell, etc.

They weren't hyped because they didn't have a silly party trick like microbenchmark performance. But they give you all the practical benefits of Rust and more.


Scala, OCaml, and Haskell all approach programming from a functional-first perspective. What no other language did before Rust was to bring those features to such a well-designed imperative core.

And while this was necessary to Rust's success, I don't think it was sufficient, insofar as it also needed a good deal of corporate backing, a great and welcoming community, and luck to be at the right place at the right time.

Haskell never tried to be more than a academic language targeting researchers. OCaml never had a big community or corporate backing. Scala never really had a niche; the most salient reason to use it is if you're already in the Java ecosystem and you want to write functional code. The value propositions for each are very different, so these language didn't receive the same reaction as Rust despite offering similar features.


Scala is distinctively a mixed FP and OOP language. There are functional proponents doing full monads and whatnot, but there is just as much follower of a more balanced approach (see Li Haoyi's libs). Though Scala definitely had/have quite a niche around it.

Well I think Scala's main problem here is it can still have runtime errors with null values, so it doesn't really have the same runtime safety guarantees pattern matching brings Rust / Haskell / OCaml. For example, this will cause a runtime panic in Scala:

https://scastie.scala-lang.org/fnquHxAcThGn7Z8zistthw

This wouldn't compile in Rust. Scala is an okay language, its main benefit as far as I can tell is its a way to write JVM code without having to write Java.


Scala 3 has a compiler flag that makes `null` its separate type, making it completely null-safe.

This would e.g. make

``` val a: String | Null = someLegacyJavaCodeReturningNullableString()

```

and explicit null check would only make the non-nullable string continue onward.


That's a theoretical problem, not a practical one. Scala programmers and Scala libraries don't use null and usually have a linter that will reject code like that. (You can hit null in Scala because you didn't check an FFI call properly, but that happens in Rust too)

The practice of software engineering and language design have improved considerably after the realization of two important facts:

1) If something is technically possible, programmers will not only do it but abuse it.

2) You can't enforce good programming practice at scale using norms.

Linters and as the sibling points out the addition of a recent compiler flag (which is kind of an admission that it's not not an issue), is the opposite approach Rust takes, which is to design the language to not allow these things at all.

> you didn't check an FFI call properly, but that happens in Rust too)

Which is why FFI is unsafe in Rust, so nulls are opt-in rather than opt-out. Having sensible security defaults is also a key learning of good software engineering practice.


> 1) If something is technically possible, programmers will not only do it but abuse it.

> 2) You can't enforce good programming practice at scale using norms.

Not quite. Programmers will take the path of least resistance, but they won't go out of their way to find a worse way to do things. `unsafe` and `mem::transmute` are part of Rust, but they don't destroy Rust's safety merits, because programmers are sufficiently nudged away from them. The same is true with unsafePerformIO in Haskell or null in Scala or OO features in OCaml. Yes it exists, but it's not actually a practical issue.

> the addition of a recent compiler flag (which is kind of an admission that it's not not an issue)

Not in the way you think; the compiler flag is an admission that null is currently unused in Scala. The flag makes it possible to use Kotlin-style null in idiomatic Scala by giving it a type. (And frankly I think it's a mistake)

> is the opposite approach Rust takes, which is to design the language to not allow these things at all.

Every language has warts, Rust included. Yes, it would be better to not have null in Scala. But it's absolutely not the kind of practical issue that affected adoption (except perhaps via FUD, particularly from Kotlin advocates). Null-related errors don't happen in real Scala codebases (just as mem::transmute-related errors don't happen in real Rust codebases). Try to find a case of a non-FFI null actually causing an issue.


C only got to its performance state, when optimizing compilers taking advantage of UB started being common thing, during the 8 and 16 bit home computer days they were hardly any better than writing Assembly by hand, hence why books like Zen of Assembly Language left such a mark.

So if we are speaking of optimizing compilers there is MLton, while ensuring that the application doesn't blow up in strange ways.

The problem is not people getting to learn these features from Rust, glad that they do, the issue is that they think Rust invented them.


> the issue is that they think Rust invented them

Sorry, my post wasn't to imply Rust invented those things. My point was Rust's success as a language is due to those features.

Of course there's more to it, but what Rust really does right is blend functional and imperative styles. The "match" statement is a great way to bring functional concepts to imperative programmers, because it "feels" like a familiar switch statement, but with super powers. So it's a good "gateway drug" if you will, because the benefit is quickly realized ("Oh, it caught that edge case for me before it became a problem at runtime, that would have been a headache...").

From there, you can learn how to use match as an expression, and then you start to wonder why "if" isn't an expression in every language. After that you're hooked.


I mean, "fearless concurrency", while a hyped-up phrase that is definitely exaggerated, compared to the C-world where you are already blowing off your leg in single-threaded code, let alone thinking of multiple threads Rust is an insanely huge win. And it shows on e.g. the small Unix tool rewrites.

Sure, rewrites are most often better on simply being a rewrite, but the kind of parallel processing they do may not be feasible in C.


> Yes it's a damning indictment of programming culture than people did not adopt pre-Rust ML-family languages, but it could be worse, they could be not adopting Rust either.

I'll say for a long time I've been quite pleased on the general direction of the industry in terms of language design and industry trends around things like memory safety. For a good many years we've seen functional features being integrated into popular imperative languages, probably since map/reduce became a thing thanks to Google. So I'll us all credit for coming around eventually.

I'm more dismayed by the recent AI trend of asking an AI to write Python code and then just going with whatever it outputs. I can't say that seems like a step forward.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: