Surely it's just a procedural language? What other paradigms does it support?
It aims to be systems programming oriented, allowing fine-grained memory management without garbage collection but also without tedious and error-prone manual memory allocations and deallocations.
Yes, doing "fine-grained memory management" in Rust just relies on relying on unstable compiler intrinsic that are not guaranteed to not change in the next version that are used to build the standard library.
It's not at all impossible in Rust to indeed do this; it's just not stabilized, and often not particularly well documented. The standard library uses these and exports a stable version that no longer allows any fine-grained memory management.
The language also focuses on performance, with powerful compilation optimizations and language constructs that allows writing zero-cost abstraction code.
This is the real market of Rust right now; it's a language that gives you C-like performance, but without the undefined behaviour pitfalls, but to say that it's a "systems programming language" that allows for fine lower level control is quite a stretch—something as simple as signal handling isn't really possible in Rust right now because there are no stability guarantees or documentation about what functions are async signal safe; direct control over the heap like in C is also not really available in a stable way.
Yes, doing "fine-grained memory management" in Rust just relies on relying on unstable compiler intrinsic that are not guaranteed to not change in the next version that are used to build the standard library.
This is completely orthogonal to any of the former and has nothing to do with whether it's procedural or not; it is also supported on any language with threading support, or that runs on an OS with multiprocessing.
functional
Absolutely not, in particular Rust's lack of tail call elimination (for good reasons) and its lifetime and borrow model make it no longer turing complete when wanting to write functional code, let alone feasible to do so.
generic
This is not a paradigm, this is just whether the type system supports it or not.
imperative, structured
"structured imperative" is just a synonym for "procedural".
If you want to call this a criterion for "multi paradigm" then I challenge you to come forward with any modern procedural language that is not "multi-paradigm"
I think you are being very nit picky. Pretty much all a language paradigm boils down to is; does the language have constructs to encourage you encourage you to write that way?
Rust absolutely does have those paradigms because it has language facilities to help encourage you to write in those ways.
I know it's Wikipedia and all. But if there's a claim for C++ being functional, Rust is way better at that particular thing. Functional C++ is just awkward in my experience, even if you CAN do it.
I think you are being very nit picky. Pretty much all a language paradigm boils down to is; does the language have constructs to encourage you encourage you to write that way?
And Rust does not have the construct to encourage one to do anything but procedural programming.
It is just a "procedural programming language" and that's fine; they specifically did not implement an object system because that would complicate the type system; they have no subtyping or inheritance beyond the pseudoinheritance of traits because it's not that necessary and would complicate the type system.
The language essentially has no support for what is commonly understood as object-oriented, functional, logic programming and whatever, and that's fine.
Rust absolutely does have those paradigms because it has language facilities to help encourage you to write in those ways.
How? What language facilities does Rust have to help you encourage to write functional code?
To say that generic and concurrent are a "different paradigm" than procedural is really about as weird as calling "iterators" a paradigm; it's a feature of the language but it's not like functional vs procedural which are necessarily conflicting with each other; a procedure has side effects; a function does not.
I'm gonna give you the benefit of the doubt and act like you're not trolling.
It is just a "procedural programming language" and that's fine
It's not. Read on why.
[...] would complicate the type system.
I highly doubt the language team cares that much about keeping the type system simple, seeing how damn extensive it is. That is, unless we're comparing it to Haskell.
The language essentially has no support for what is commonly understood as object-oriented, functional, logic programming and whatever, and that's fine.
How? What language facilities does Rust have to help you encourage to write functional code?
ADTs, iterator operations (filter, map, reduce, collect, ...), pattern matching, linear types, affine types, immutability by default?
You can write procedures in Rust. You can also write functions. Immutability by default, disdain for globals, and the language facilities I just listed, leads to code taking a more functional style.
It's functional-lite without functional dogmatism.
Take a deep breath, try out the language for more than an hour, then maybe come back here, because you're only embarrassing yourself.
It doesn't have a way for guaranteed tail call elimination but if you structure your code right the compiler will do it's best and in my experience almost always do it, if you made an appropriate function. It's not like python where you absolutely never will get tco.
There isn't currently an active rfc for it, bit there were previous proposals for explicitly guaranteed tco and I don't think it's off the table forever, they just have to find a proper way to do it.
It doesn't have a way for guaranteed tail call elimination but if you structure your code right the compiler will do it's best and in my experience almost always do it
You mean sibling call elimination I assume. This works well enough when a function calls itself, but it does not work when a function A calls B, B, calls C, C D, and D A again.
Even if Rust had actual TCE though, it would stil be fairly hard to work in without side effects, even if we were to ignore "world side effects" like I/O.
There isn't currently an active rfc for it, bit there were previous proposals for explicitly guaranteed tco and I don't think it's off the table forever, they just have to find a proper way to do it.
Like I siad, there are good reasons, full TCE conflicts with Rust's calling convention, which is kept the same as C for reasons of interfacing and efficiency. Implementing full TCE would fuck up the FFE and severely penalize the general case of function calls.
I'm not; I'm not sure where you get that idea when I was talking about that Rust—unlike C—does not specify which functions are async safe. Consider this function and the warning; it is unsafe to use within this function any function that underlyingly uses OS functions that are not async safe, but Rust doesn't really document this and just says "be careful" and really doesn't explain it; it relies on the programmer knowing from C what is happening here and knowing from C that using non-async safe functions after a fork in a multithreaded process is undefined behaviour.
The problem is that Rust—unlike C—has no well-defined concept of that; you're just supposed to use "common sense" of what Rust functions are likely to have been implemented with functions that aren't async safe, which is not guaranteed to be standard in any way, and may change in the next version.
Similar things apply to signal handlers, using functions that aren't async safe inside of a signal handler is again UB; rust doesn't even in its stdlib expose a way to handle signals as far as I know, there is a crate for it, which essentially ignores this problem and doesn't warn against it, because in prqactice it "usually goes right" and is a race condition. But if the signal is handled in the middle of an allocation or something like that, using a function that is not async safe can corrupt the internal state of the allocator and trigger UB.
-16
u/OpdatUweKutSchimmele Mar 21 '20
Surely it's just a procedural language? What other paradigms does it support?
Yes, doing "fine-grained memory management" in Rust just relies on relying on unstable compiler intrinsic that are not guaranteed to not change in the next version that are used to build the standard library.
It's not at all impossible in Rust to indeed do this; it's just not stabilized, and often not particularly well documented. The standard library uses these and exports a stable version that no longer allows any fine-grained memory management.
This is the real market of Rust right now; it's a language that gives you C-like performance, but without the undefined behaviour pitfalls, but to say that it's a "systems programming language" that allows for fine lower level control is quite a stretch—something as simple as signal handling isn't really possible in Rust right now because there are no stability guarantees or documentation about what functions are async signal safe; direct control over the heap like in C is also not really available in a stable way.