Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust code example #2

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Rust code example #2

wants to merge 1 commit into from

Conversation

joseluisq
Copy link

Hi Antonio,
As you requested here the code example but this time in Rust.
Since I'm using only the rust compiler rustc you can just compile and run it directly from your terminal, only make sure that you have a stable Rust toolchain available in your system.
This example is very generic so represent no more than the transcription of your previous examples so that it can be improved, for sure. It also doesn't include any benchmarks just a couple of unit tests. So feel free to improve it.

To compile and run test suite use:

$ rustc -V
# rustc 1.52.0 (88f19c6da 2021-05-03)

$ rustc --test sorted.rs && ./sorted

# running 1 test
# test tests::simple_tests ... ok

# test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

To compile and run an optimized build (main function) use:

$ rustc -C opt-level=3 sorted.rs && ./sorted

# warning: function is never used: `sorted`
# --> sorted.rs:1:4
#  |
#1 | fn sorted(xs: Vec<f64>) -> Vec<f64> {
#  |    ^^^^^^
#  |
#  = note: `#[warn(dead_code)]` on by default
#
# warning: 1 warning emitted

# TODO: implement benchmarks, more tests or whatever you want here..

Regards.

@ddcovery
Copy link
Owner

Hi Jose Luis,
thanks for the proposal

One of the musts of this exercise, is to write the "sorted" function as an unique expression (the "declarative" or "functional" way) avoiding imperative code: It could be a regular function with an unique return statement (like the python one), a lambda with no return, etc...

I wrote this example that is an expression, but it is really complex/verbose (I'm newbie with Rust) and I decided not to include the code: The result is hard to understand and destroys the idea of expressiveness that is the objective of the article (compare it with the beautiful Scala example)

fn sorted(xs:Vec<f64>)->Vec<f64> {
    return match xs.len() {
        0 => Vec::<f64>::new(),
        _ => 
            sorted( xs[1..].iter().filter(|&x|x<=&xs[0]).map(|&x|x).collect() ).iter().
            chain( iter::once(&xs[0]) ).
            chain( sorted( xs[1..].iter().filter(|&x|x>&xs[0]).map(|&x|x).collect() ).iter() ).
            map(|&x|x).collect(),
    }
}

It would be perfect if you can rewrite your example as an unique expression (match is really powerful)...

Other problem I found is I can't write sorted as a generic function i.e.: fn sorted<T:Ord>(xs:Vec<T>)->Vec<T> because trait Ord is not implemented for f32 neither f64 and I really don't know how to solve it. Any case, this is not important for the objectives of the article.

@joseluisq
Copy link
Author

I understand.
I think there are obstacles here. And It's not the match expression that can serve to the purpose of one statement but instead Rust's lifetimes, interation over floats and total ordering of them. As you mentioned, saying that Ord trait is not implemented for floats. However as far as I know this is something that is out of Rust's scope because of NaNs.
Anyway I think you want to have a look at PartialOrd trait if you don't want total ordering of floats and try to implement it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants