digitalmars.D - From two small Rust tutorials
- bearophile (114/118) Aug 16 2014 Recently I've found two very small introductions to the Rust
- b (4/4) Aug 16 2014 rust makes me sad. So good. Unique types. Type classes. Nice.
- Ziad Hatahet via Digitalmars-d (5/7) Aug 17 2014 Some form of overloading is possible using traits and generics.
- Paulo Pinto (3/12) Aug 17 2014 And currying
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
Aug 16 2014
rust makes me sad. So good. Unique types. Type classes. Nice. Wait. no.. overloading... why.........
Aug 16 2014
On Sat, Aug 16, 2014 at 8:01 AM, b via Digitalmars-d < digitalmars-d puremagic.com> wrote:no.. overloading... why.........Some form of overloading is possible using traits and generics. -- Ziad
Aug 17 2014
On Monday, 18 August 2014 at 04:32:42 UTC, Ziad Hatahet via Digitalmars-d wrote:On Sat, Aug 16, 2014 at 8:01 AM, b via Digitalmars-d < digitalmars-d puremagic.com> wrote:And curryingno.. overloading... why.........Some form of overloading is possible using traits and generics. -- Ziad
Aug 17 2014