Live data from Hacker News

Rust vs. Haskell

serokell.io

121–130 of 189 posts

Re: Rust vs. Haskell

#121
post #94

Earlier quoted context omitted.

> "Worthless" is a bit strong. No, TCO is worthless, it’s an unreliable optimisation.

If given explicit support in a language then no it's not. Especially with the keyword approach rust is taking, the compiler will guarantee the semantics. Do you believe the exec system call is similarly unreliable at replacing your process image? Amazing that unix systems work at all

> If given explicit support in a language then no it's not. Especially with the keyword approach rust is taking, the compiler will guarantee the semantics.

Then it's TCE not TCO.

> Do you believe the exec system call is similarly unreliable at replacing your process image?

Exec is entirely unlike TCO. If exec was a syscall which sometimes did and sometimes did not replace your process image, then it'd be like TCO, and it'd be similarly unreliable.

Re: Rust vs. Haskell

#122

Earlier quoted context omitted.

Lol. "fundamentally broken" and yet I've been using them with little to no friction for pretty close to a decade now. If that's what you think "broken" means, then, well, you've completely devalued the word. This right here is what we call sensationalism folks. Now if you said, "Rust has some rough points at the intersection of generics, closures and async programming," I'd say that's absolutely true!

> "fundamentally broken" and yet I've been using them with little to no friction for pretty close to a decade now. This might rather confirm my point, since engineers using a specific programming language quite often have a contorted picture of how code in other languages is written, as they become more and more acquainted with their main tool. If we compare Rust closures with those of ML languages, it becomes pretty…

The sneer is strong with this one.

> This might rather confirm my point

It might, but it doesn't, because I don't only use Rust. Notice also how you've moved the goalposts from "fundamentally broken" (sensationalist drivel) to "how natural closures are in ML and tricky in Rust" (a not unreasonable opinion with lots of room to disagree on the degree of "natural" and "tricky").

Re: Rust vs. Haskell

#123

One important thing Rust and Haskell have in similar is the nearly complete absence of an endeavour to unify things. As more fancy type system features get added, both languages become quite complex, thus increasing the learning curve and compiler complexity. This is quite aptly expressed by the recent paper on dependent types [1]: > Previous versions of Haskell, based on System Fω , had a simple kind system with a f…

> currently it's not quite clear what's the best way to integrate dependent types with systems programming. Dependent types dispense with the phase separation between compile-time and run-time code, which is inherent to system languages. So you can easily have dependent types in a systems language as part of compile-time evaluation , but not really as a general feature. It would work quite similar to the "program ext…

Yeah, the main problem with dependent types being used in low-level programming is that they're now able to perform arbitrary computation. That's why I think castrated dependent types might do the trick, since if you accept only integer indices as parameters to types, then you can boil down type checking to constraint solving without actually performing arbitrary computation.

Re: Rust vs. Haskell

#127

Earlier quoted context omitted.

Quite a few of Rust's features were borrowed from or inspired by ones in Haskell - albeit often modified to be more suitable for systems programming (and systems programmers!). Most Haskellers I know are quite fond of Rust :)

I think Rust's features were actually inspired by OCaml rather than Haskell. Rust was originally written in OCaml, and OCaml feels a lot more similar to Rust than Haskell does. Of course Haskell is heavily influenced by ML so it also has a lot of the same features.

It doesn't have to be one or the other :). OCaml and Haskell are two great languages that the Rust designers were familiar with.

The big thing IMO that makes Rust feel like Haskell is the pervasive use of traits and `#[derive(...)]` which is directly analogous to the pervasive use of typeclasses and `deriving` in Haskell.

Re: Rust vs. Haskell

#128

Earlier quoted context omitted.

Indeed. My (and by no means am I the only one) mental model of closures is really simple. A closure is a struct with no name, and the free variables of the closure are fields in the struct. If the closure is annotated with 'move', then those fields are owned, otherwise the fields are borrowed and the lifetime parameter on the struct is the shortest of the bunch. Then, calling the closure is just calling it with 'self…

Your example indeed perfectly demonstrates the subtlety of closures in Rust. Now let's imagine I want to return a nested closure, e.g., `impl Fn(i32) -> impl Fn(i32) -> i32`, or something like that: fn adder(x: i32) -> impl Fn(i32) -> impl Fn(i32) -> i32 { move |y| move |z| y + x + z } Alright, I can't. I can do that for a single closure, but can't for two or more of them. Here's why we have `#![feature(impl_trait_in…

My example didn't demonstrate the subtlety here, but it inspired your example, which of course does demonstrate some subtlety. And as I acknowledged in another comment, I of course agree there are subtleties to closures in Rust! And I agree there are useful nightly features that unlock additional use cases. Rust gives you enough rope to hang yourself with. For example, if you're okay with a heap allocation (like I assume you might be in a language with "non-broken closures" lol), then you don't need nightly Rust:

    fn adder(x: i32) -> impl Fn(i32) -> Box i32> {
        move |y| Box::new(move |z| y + x + z)
    }

    fn main() {
        let add23 = adder(2)(3);
        assert_eq!(10, add23(5));
        assert_eq!(13, add23(8));
    }
It's almost like "fundamentally broken" (not just "broken" but "fundamentally broken") and "has subtlety" are two totally different things. What a fucking revelation.

Re: Rust vs. Haskell

#129

Earlier quoted context omitted.

"Worthless" is a bit strong. The Rust devs want to add TCO/TCE, but there are still problems left to solve. The "become" keyword is already reserved in anticipation of guaranteed tail calls being added. https://github.com/rust-lang/rfcs/issues/2691

> "Worthless" is a bit strong. No, TCO is worthless, it’s an unreliable optimisation.

Compiler optimizations are best-effort. -O3 gets you 90% of the optimization for 10% of the work of writing hand-rolled assembly. Individual optimizations are not guaranteed, and sometimes even regress in newer compiler versions, but everyone uses them because overall programs run much faster with optimizations than without. I don't see how TCO is any different. Would you say all optimizations are worthless because they're not guaranteed?

Re: Rust vs. Haskell

#130
post #22

About Haskell's function type annotations: "But it usually results in a warning, and adding a type signature is a good practice." I prefer Rust's way of doing this. When you're a beginner it ensures that you're passing and returning the proper type to and from the function, you kind of have the function as a guard which ensures that you're using the correct types.

I find type errors in HM typing systems can sometimes be quite obscure and misleading, due to omnipresent type inference. Writing type signatures can save you from that. For example, even if the type signature is quite "obvious", you can erroneously plug in some other type into the function, which triggers the type system to underline the function being defined instead of the function call.
Post reply on HN