Recently I've found two very small introductions to the Rust language. Below I list some of the things I've found in them.

The first tutorial is:
http://matej-lach.me/rust-basics/

------------------

The Rust tuple syntax similar to Kenji's:

let (i, result) = (0i, 0i);
let (x, y, z) = (15i, "string", 29.99f64);
let (mut s, a, mut m) = ("can change", "cannot", "can");

------------------

Nice uniform names for the integral values (but uint and int are variable length, I don't know if this is a good idea, I don't like this much):

Rust has the following primitive numeric types: u8, i8, u16, i16, u32, i32, u64 and i64 - it also has the aliases int and uint for i64 or i32 and u64 or u32 respectively, (depending on whether the OS is 64 or 32-bit).<

------------------

The switch syntax supports floating point intervals too:

match x {
    1.0..1.99 => println!("x is between one and two"),
    2.0..2.99 => println!("x is between two and three"),
    3.0..3.99 => println!("x is between three and four"),
    4.0..4.99 => println!("x is between four and five"),
    5.0..5.99 => println!("x is between five and six"),
_ => println!("x is bigger than five") // catches all other possible values of `x`
}


That feature can be added to D too, if it's desired:

void main() {
    double x;
    case (x) {
case 1.0: .. case 1.99: return writeln("x is between one and two"); case 2.0: .. case 2.99: return writeln("x is between two and three"); case 3.0: .. case 3.99: return writeln("x is between three and four"); case 4.0: .. case 4.99: return writeln("x is between four and five"); case 5.0: .. case 5.99: return writeln("x is between five and six"); default: return writeln("x is bigger than five");
}


But what about x = 1.999? That Rust code looks buggy.

This hypotetical D code looks more correct, so it's tricky (I used T because the nextDown of a float is different from the nextDown of a double/real):

void main() {
    import std.math: nextDown;
    double x;
    alias T = typeof(x);
    case (x) {
        case 1.0: .. case nextDown(T(2)):
            return writeln("x is between one and two");
        case 2.0: .. case nextDown(T(3)):
            return writeln("x is between two and three");
        case 3.0: .. case nextDown(T(4)):
            return writeln("x is between three and four");
        case 4.0: .. case nextDown(T(5)):
            return writeln("x is between four and five");
        case 5.0: .. case nextDown(T(6)):
            return writeln("x is between five and six");
        default:
            return writeln("x is bigger than five");
}

------------------

The second tutorial:
http://pudgepacket.github.io/rust/2014/08/11/taste-of-rust-pt-2/


A little function that converts a string (line) to a vector of doubles:

fn extract_line_data<T: std::from_str::FromStr>(line: &str) -> Vec<T> { line.trim().split(' ').filter_map(|s| from_str::<T>(s)).collect()
}


The same function written in a more didactic style:

fn extract_line_data<T: std::from_str::FromStr>(line: &str) -> Vec<T> {
    // line = "f 1 2 3 4\n"

    // Remove line endings
    let trimmed = line.trim();
    // trimmed = "f 1 2 3 4"

    // Split on space
    let split = trimmed.split(' ');
    // split = ["f", "1", "2", "3", "4"]

    // Map from_str over the split array
// collect all the successfuly converted values into a vector let converted = split.filter_map(|s| from_str::<T>(s)).collect();
    // converted = [1, 2, 3, 4]

    return converted
}


The from_str is related to std.conv.to (but I think it overloads the return type, as in the Haskell function, that is not possible in D).

When you try to convert the "f" string using from_str it doesn't raise an exception like std.conv.to because from_str returns an Option<T>, similar to Phobos Nullable!T.

So they have used filter_map to filter away the Null conversions. So it's similar to this D code:


T[] extractLineData(T)(in string line) {
    return line
           .split
           .map!(s => s.maybeTo!T)
           .filter!(m => !m.isNull)
           .map!(m => m.get)
           .array;
}


Where maybeTo is similar to std.conv.to but returns a Nullable!T (https://d.puremagic.com/issues/show_bug.cgi?id=6840 ).

Probably it's a good idea to add to Phobos some more functions (like filterMap) that manage ranges of Nullables in a smarter way (this is also quite commonly done in Scala language).

Bye,
bearophile

Reply via email to