←back to thread

517 points bkolobara | 8 comments | | HN request time: 1.432s | source | bottom
Show context
BinaryIgor ◴[] No.45042483[source]
Don't most of the benefits just come down to using a statically typed and thus compiled language? Be it Java, Go or C++; TypeScript is trickier, because it compiles to JavaScript and inherits some issues, but it's still fine.

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

replies(17): >>45042692 #>>45043045 #>>45043105 #>>45043148 #>>45043241 #>>45043589 #>>45044559 #>>45045202 #>>45045331 #>>45046496 #>>45047159 #>>45047203 #>>45047415 #>>45048640 #>>45048825 #>>45049254 #>>45050991 #
pornel ◴[] No.45043105[source]
To a large extent yes, but Rust adds more dimensions to the type system: ownership, shared vs exclusive access, thread safety, mutually-exclusive fields (sum types).

Ownership/borrowing clarifies whether function arguments are given only temporarily to view during the call, or whether they're given to the function to keep and use exclusively. This ensures there won't be any surprise action at distance when the data is mutated, because it's always clear who can do that. In large programs, and when using 3rd party libraries, this is incredibly useful. Compare that to that golang, which has types for slices, but the type system has no opinion on whether data can be appended to a slice or not (what happens depends on capacity at runtime), and you can't lend a slice as a temporary read-only view (without hiding it behind an abstraction that isn't a slice type any more).

Thread safety in the type system reliably catches at compile time a class of data race errors that in other languages could be nearly impossible to find and debug, or at very least would require catching at run time under a sanitizer.

replies(4): >>45043414 #>>45043440 #>>45047837 #>>45052706 #
zelphirkalt ◴[] No.45043414[source]
What annoys me about borrowing is, that my default mode of operating is to not mutate things if I can avoid it, and I go to some length in avoiding it, but Rust then forces me to copy or clone, to be able to use things, that I won't mutate anyway, after passing them to another procedure. That creates a lot of mental and syntactical overhead. While in an FP language you are passing values and the assumption is already, that you will not mutate things you pass as arguments and as such there is no need to have extra stuff to do, in order to pass things and later still use them.

Basically, I don't need ownership, if I don't mutate things. It would be nice to have ownership as a concept, in case I do decide to mutate things, but it sucks to have to pay attention to it, when I don't mutate and to carry that around all the time in the code.

replies(5): >>45043496 #>>45043550 #>>45043678 #>>45044243 #>>45050174 #
timeon ◴[] No.45043550[source]
> While in an FP language you are passing values

By passing values do you mean 'moving'? Like not passing reference?

replies(1): >>45044453 #
1. zelphirkalt ◴[] No.45044453[source]
Yes, I guess in Rust terms, that is called moving. However, when I have some code that "moves" the value into another procedure, then the code after that call, can no longer use the moved value.

So I want to move a value, but also be able to use it after moving it, because I don't mutate it in that other function, where it got moved to. So it is actually more like copying, but without making a copy in memory.

It would be good, if Rust realized, that I don't have mutating calls anywhere and just lets me use the value. When I have a mutation going on, then of course the compiler should throw error, because that would be unsafe business.

replies(2): >>45044767 #>>45045055 #
2. asa400 ◴[] No.45044767[source]
I'm not sure how what you're describing is different from passing an immutable/shared reference.

If you call `foo(&value)` then `value` remains available in your calling scope after `foo` returns. If you don't mutate `value` in foo, and foo doesn't do anything other than derive a new value from `value`, then it sounds like a shared reference works for what you're describing?

Rust makes you be explicit as to whether you want to lend out the value or give the value away, which is a design decision, and Rust chooses that the bare syntax `value` is for moving and the `&value` syntax is for borrowing. Perhaps you're arguing that a shared immutable borrow should be the default syntax.

Apologies if I'm misunderstanding!

3. NIckGeek ◴[] No.45045055[source]
Couldn't you just pass a reference to your value (i.e. `&T`)? If you absolutely _need_ ownership the function you call could return back the owned value or you could use one of the mechanisms for shared ownership like `Rc<T>`. In a GC'd functional language, you're effectively getting the latter (although usually a different form of GC instead of reference counting)
replies(1): >>45045332 #
4. zelphirkalt ◴[] No.45045332[source]
I think I could. But then I would need to put & in front of every argument in every procedure definition and also deal with working with references inside the procedure, with the syntax that brings along.
replies(2): >>45045629 #>>45047259 #
5. Mond_ ◴[] No.45045629{3}[source]
Fair to be annoyed by this, but not very interesting: This is just a minor syntactical pattern that exists for a very good reason.

Syntax is generally the least interesting/important part of languages.

6. pepa65 ◴[] No.45047259{3}[source]
When you pass &variable, I don't think it affects the syntax inside the called function, does it?
replies(1): >>45047610 #
7. asa400 ◴[] No.45047610{4}[source]
Correct. If you then want to subsequently re-reference or dereference that reference (this happens sometimes), you'll need to accordingly `&` or `*` it, but if you're just using it as is, the bare syntactical `name` (whatever it happens to be) already refers to a reference.
replies(1): >>45053161 #
8. gf000 ◴[] No.45053161{5}[source]
Also, Rust does implicit dereferencing, so it's not that much of an issue in practice.