DEV Community

Discussion on: Getting Started with Rust

Collapse
 
youroff profile image
Ivan Yurov

I'm not sure that there's too much of FP in Rust. With all nice abstractions and lambdas, Rust discourages programmers from using by-value arguments, since in move semantic it can only happen once and when borrowing (especially mutably) we're dealing with references and mutate state in place which is be definition procedural.

Collapse
 
leob profile image
leob

Not sure if I understand your argument - when you say "when borrowing (especially mutably)" then you already assume that you're using mutable variables, implying that you're using a procedural rather than an FP approach ... that's an option, but not the only way to do things.

When going through Rust's official docs (the programming language tutorial) they seem to emphasize abstract data types and interfaces before they do "OO" constructs - and variables being immutable by default promotes an FP approach as well. Could be me, but many concepts in Rust reminded me a LOT of Haskell.

Of course Rust is not a pure FP language, so you can program procedurally if you want, but then in my opinion you're not using Rust's full power.

Thread Thread
 
youroff profile image
Ivan Yurov • Edited

Let's figure out what is functional first. You mentioned Haskell, and even though it's been many years since I played with it, but if I'm not mistaken it doesn't allow mutation of a function arguments. So functions are pure: they take values and return a fresh value. Even though you can formally do the same with Rust, it won't work in practice, here's the example.

Suppose you have a Vector and a function length(list: Vector<T>) -> i32 that returns length. If you call it on a vector, it'll be moved. And none of the subsequent calls on a variable holding that vector will work. Instead Rust encourages using borrowing: length(list: &Vector<T>) -> i32 and passing refs in this case. And in this case it's perfectly fine to call functions (procedures?) with refs multiple times.

Now why I call these procedures: do_something(&mut self) would not return anything, and rather mutate the state of the struct it's attached to. So technically it's not a function, but a procedure that mimicks methods from OOP.

And I guess it's perfectly fine, especially given that it's dictated by the reasons of performance and explicit resources control, but for someone with functional mindset (such as myself) it might be quite painful to adjust.

Thread Thread
 
leob profile image
leob

I won't argue with you on this particular example, but maybe the result (whether or not you run into these limitations) depends on how you approach the problem - point is I've seen (real world) Rust code on a project which looked and felt way more "FP" than procedural to me. But, it's more like I "dabbled" in Rust than that I could consider myself truly knowledgeable (let alone an expert) in it, I'm definitely not in a position to prove anything.

Some interesting points regarding whether or not Rust can be considered "functional":
fpcomplete.com/blog/2018/10/is-rus...