5 ms·
I think about it the other way; Rust is an ML with a borrow checker. Most of the stuff I hear people gushing about in Rust is IMO them experiencing what's it's
by debo_ 3y ago
I think about it the other way; Rust is an ML with a borrow checker. Most of the stuff I hear people gushing about in Rust is IMO them experiencing what's it's like to write ML.
- satvikpendem 3y agoYes and no, Rust is ML inspired but it is still way too imperative and not as functional to be called a true ML. But yes, things like Result and Option types, do-notion via "?," at least for Results and Options, algebraic data types are all part of the appeal. There sadly are still no higher kinded types though, but that is a difficult problem to solve and most won't encounter such problems anyway in day-to-day coding, so the contributors made generic associated types instead as an alternative.
- greydius 3y ago> still way too imperative and not as functional to be called a true ML As a Haskell fanboy, this is how I feel about Ocaml and F#.
- satvikpendem 3y agoWhat are your thoughts on Idris and other Haskell derivatives? As well as the HVM and its Lisp-like Haskell-like combo of a language [0]? [0] https://github.com/HigherOrderCO/hvm https://github.com/HigherOrderCO/hvm
- debo_ 3y agoTrue. In this case the author is speaking specifically about OCaml, which is quite comfortable to write imperatively. I think the thing that tickles most people about Rust is the thoroughness of the type inference and type checking, which one generally gets from any ML.
- vlovich123 3y agoYeah but traditional ML languages are ass slow. If I want to write applications that are that slow, why not use something that targets the browser or something like Ruby or Python that has a much deeper ecosystem to leverage? Unless you’re just playing around with building a language and trying out different ideas or you think it’s better at some other axis (eg lower defect rate). But I’ve generally found that my incident rate for bugs doesn’t change with languages. What rust has done successfully and “ML” languages have not is how to engage a broader community by exploiting a weakness in some class of problems they can do better on that existing languages cannot. That’s why they shifted into systems languages. Memory safety in systems languages was critically important and ML languages are typically too slow and memory hungry so Rust adopted some of the C/C++ communities obsession with speed and memory usage philosophies while allowing for much safer code to be written. I think it’s safe to say they’ve finally dealt a “COBOL” like blow in that completely new code being written is unlikely to be C++ and C++ developer salaries will keep going up because it’s a difficult niche. will take a few decades to play out because C and C++ is so heavily entrenched. And who knows, maybe the memory safety efforts the standards body is taking will help but I think ultimately it will only be useful for hardening existing codebases but that’s a temporary patch on a bleed. Rust used that initial wedge to jam in a code repository, making testing and benchmarking easier, etc etc. some of the Rust libraries are insanely high quality and waaay easier to work with than in C++ land (even at Google and Facebook where it was a record level of easy)
- zogrodea 3y agoI don't think ML languages tend to be that slow, depending on what you compare them with and which member of the family you are using for comparison. If we have three stages: (1) system languages, (2) higher level languages like Dart, Java, C#, (3) very high level languages like Python and Ruby, then the those among the most popular languages in the ML family (OCaml and F#) comfortably occupy the same level as (2). Maybe that's not what you're after. OCaml's more rare bytecode implementation (instead of native code) is about on par with Python and SML/NJ is pretty slow as well (although faster SML implementations like MLTon exist).
- pjmlp 3y ago
- dan-robertson 3y agoI think the ‘is or is not a true ML’ argument is a bit unwinnable so I won’t comment on it. Regarding ‘functional’, Rust makes it harder to write in a traditional functional style because (a) it doesn’t offer tail-call elimination and (b) the resource-ownership tracking makes most normal functions feel side-effecty. I think it’s pretty hard to have a natural-feeling functional style without cheap allocation and some kind of deferred automatic deallocation (this is carefully phrased to allow for a garbage collector or a kind of arena allocation) I don’t think this is that bad for rust though. For (a), it turns out that tail calls can make debugging harder, and they can be incompatible with certain type system changes you might want in an ML, and lots of OCaml (perhaps not a true ML?) in practice uses little explicit recursion and instead first-class functions with names like map and iter rather than recursion. So I don’t really think it’s very important. Rust also has these first-class iterator functions although a bit less of map for containers that can have many things (e.g. vectors). Rust iterations allow for writing code that is more functional when memory/performance are stronger constraints because the pipeline gets composed together instead of producing lots of intermediate objects. For (b) I guess the big difference is that the usual tool in functional programming for manipulating data is creating new copies of immutable data whereas in rust it is controlling ownership and then just updating it (a middle ground may be koka where you write code in the former style but the compiled code inspects recounts to potentially just mutate instead)
- sakras 3y ago> it doesn’t offer tail-call elimination Why not? I’ve heard people say this about C too and I never understood it: LLVM and GCC both have optimization passes that perform tail-call elimination.
- Measter 3y agoTypically when people say that they mean that the language doesn't have guaranteed tail-call optimization. You can certainly write Rust that has the TCO pass applied, but it can be brittle because it's just an optimisation pass that might not happen.
- dan-robertson 3y ago
- cmrdporcupine 3y agoThe ? thing, didn't that get borrow from Swift, in fact?
- dgacmu 3y agoIANASE (swift expert), but the rust ? operator is used for error propragation in the same way that the try operator in swift is. Swift's ?? operator is for unwrapping an option type: x ?? default, similar to x.unwrap_or(default) in Rust. (Swift's ? is the ternary operator, as in C; rust does not have a ternary operator, using expression-if instead). Applied to a type, swift's ? is the same as Option<x> in Rust. Rust's first mechanism for error propagation was the now-deprecated try!() macro, which did basically the same thing.
- tomca32 3y agoCreator of the Rust language Graydon Hoare is working on Swift, so it’s probably the other way around
- u320 3y agoHe left Rust long before ? was introduced.
- tomca32 3y agooh fair enough. Didn't know the timing of that, so I thought it was connected.
- steveklabnik 3y agoAs far as I know, Graydon hasn’t been working on Swift for a few years now.
- masklinn 3y agoNo. For starters ? was introduced by C# 2.0 almost 10 years before Swift appeared so it would have been lifted from that if anything, but then Rust’s ? has completely different semantics than everyone else.
- preommr 3y agoAlmost like people want some functional features without all the extra baggage. I guess I would even say it's like... most people just want the banana, but got a gorilla holding the banana and the rest of the jungle as well.
- debo_ 3y agoI don't think it's the functional part of ML that tickles them. I think it's the thoroughness of the type inference and type checking.
- cglong 3y agoAt least in my piece of corporate software engineering, I'm looking at Rust as a "gateway drug" for FP. Management doesn't want to take the risk of investing in FP, so reliable choices like Java and C++ are usually endorsed; the safety aspects of Rust are a much stronger argument for them.
- vips7L 3y agoI don't think the safety aspects are a much stronger argument. Managed languages like Java and C# are safe. The garbage collector isn't going to let you ++ your way into remote code execution and most corporate software engineering isn't heavily concurrent. I think a stronger argument would be to advocate for a more functional language on the same runtime, like Scala or F#.
- cmrdporcupine 3y agoJava and C# will not provide any sanity check on your use of locks and shared mutable state though. But the Rust borrow checker will. It won't prevent deadlock or race conditions, but it will at least guide you there much better than those pass-by-mutable-reference OO languages will.
- vips7L 3y ago99.9% of all code written in these languages uses a thread per request model. Objects never go over a thread boundary. Using rust will only complicate these code bases for concerns that will never occur. …and if you’re concerned about mutability you can use an immutable first language like Scala or F#.
- whateveracct 3y agoML with a borrow checker is a bit of an oxymoron though. Because proper closures (the kind Rust can't do) are essential for the classic functional programming that ML represents.
- chmod600 3y agoCan you explain "proper closures"?
- bobbylarrybobby 3y agoI would hazard that this means closures that can capture (shared) state. In Rust, a closure’s data must either be moved into the closure or outlive the closure (dangling pointers etc etc). In most other languages, GC allows closures to keep a handle to any data at all.
- zozbot234 3y agoIf you want a closure to outlive the outside bindings of its captures and thus have shared control over their lifecycle (which is the default behavior of closures in most FP languages) you can easily use Rc<> or Arc<> to that effect. Rust just forces you to be explicit about it.
- whateveracct 3y agoExactly - sharing is the core of FP
- iopq 3y agoML does garbage collection, if it didn't need it it wouldn't do it.
- pjmlp 3y agoNope, that is what an ML with linear types does.
- ReleaseCandidat 3y agoJane Street just entered the room: https://blog.janestreet.com/oxidizing-ocaml-locality/ https://blog.janestreet.com/oxidizing-ocaml-locality/ This part specially about closures: https://blog.janestreet.com/oxidizing-ocaml-ownership/ https://blog.janestreet.com/oxidizing-ocaml-ownership/ https://blog.janestreet.com/oxidizing-ocaml-parallelism/ https://blog.janestreet.com/oxidizing-ocaml-parallelism/ And yes, their changes introduce quite some additional syntax.