Being interested in using Rust for numerical and statistical computation, here are my wishes (in order of importance).
Extend the current range and pattern notation (...
, ..
) to allow left / right inclusive or exclusive bounds (...
, ..<
, >..
, >.<
)
I can see at least three use cases:
- Inclusive/exclusive patterns are IMO required to use
match
with floats, example:
match x {
20.0>.. => Ok("oversize"),
10.0>.. => Ok("class 2"),
0.0... => Ok("class 1"),
_ => Err(some_error),
}
- Inclusive/exclusive patterns would be useful in
if
expressions, to avoid writing two conditions (similarly to ternary operators), example:
if v in 0.0...10.0
- Inclusive/exclusive ranges would be useful for instance for discretization of intervals. Example, to compute and plot function 1/x with x going from 0 (excluded) to 10 (included):
let x = (0.0>..10).step_by(0.001).collect::<Vec<_>>();
let y = x.iter().map(|x| 1.0 / x).collect::<Vec<_>>();
The extended notation could coexist with the current one, with ..
and ..<
being synonyms, or otherwise ..
could be deprecated in future. This has been discussed in the following thread:
Optional args, default args, variable-arity args
This has been discussed in the following thread:
IMO one of the best languages with this regards is R, I would take it as a reference:
Tuple iteration
This has been discussed in the following thread:
Example:
let z = (x.iter(), y.iter()).map(|xi, yi| xi + yi).collect::<Vec<_>>();
or:
let z = (x, y).iter().map(|xi, yi| xi + yi).collect::<Vec<_>>();
Iterators for multidimensional arrays
I suggested chaining two or more .iter()
methods in the following thread:
However, I now think there are better options. One would be to have for instance methods .iter2()
, .iter3()
, etc. Method .iter2()
would accept an optional parameter to specify which dimension to iterate first, iter3()
would accept two optional parameters etc. Of course .enumerate()
method would need to output more than one index with these methods.
Another option, IMO even better, would be to have method .multi_iter()
accepting N optional parameters. With no parameters, .multi_iter()
would iterate through all dimensions in order, while for instance .multi_iter(2, 1)
would iterate first through the second dimension and then through the first one.
The reason why for the first dimension I wrote 1
instead of 0
, is because a negative sign could be used to iterate in reverse order. This capability could be added to the one-dimension method too, therefore either .iter()
or .iter(1)
would iterate a vector in direct order, while .iter(-1)
would iterate in revere order.
Example, to multiply each element of matrix x
with each element of matrix y
transposed:
let z = (x.multi_iter(), y.multi_iter(2, 1)).map(|xi, yi| xi * yi).collect::<<Vec<Vec<_>>>();