I know that Rust provides some additional compile-time checks because of its stricter type system, but it doesn't come for free - it's harder to learn and arguably to read
I know that Rust provides some additional compile-time checks because of its stricter type system, but it doesn't come for free - it's harder to learn and arguably to read
I like to call it getting "union-pilled" and it's really hard to accept otherwise statically-typed languages once you become familiar.
(* Expressions *)
type Exp =
UnMinus of Exp
| Plus of Exp * Exp
| Minus of Exp * Exp
| Times of Exp * Exp
| Divides of Exp * Exp
| Power of Exp * Exp
| Real of float
| Var of string
| FunCall of string * Exp
| Fix of string * Exp
;;
let rec tokenizer s =
let (ch, chs) = split s in
match ch with
' ' -> tokenizer chs
| '(' -> LParTk:: (tokenizer chs)
| ')' -> RParTk:: (tokenizer chs)
| '+' -> PlusTk::(tokenizer chs)
| '-' -> MinusTk::(tokenizer chs)
| '*' -> TimesTk::(tokenizer chs)
| '^' -> PowerTk::(tokenizer chs)
| '/' -> DividesTk::(tokenizer chs)
| '=' -> AssignTk::(tokenizer chs)
| ch when (ch >= 'A' && ch <= 'Z') ||
(ch >= 'a' && ch <= 'z') ->
let (id_str, chs) = get_id_str s
in (Keyword_or_Id id_str)::(tokenizer chs)
| ch when (ch >= '0' && ch <= '9') ->
let (fl_str, chs) = get_float_str s
in (RealTk (float (fl_str)))::(tokenizer chs)
| '$' -> if chs = "" then [] else raise (SyntaxError (""))
| _ -> raise (SyntaxError (SyntErr ()))
;;
Hint, this isn't Rust.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.
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.
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).
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.
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.
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.
> 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.