What is Python's *Args and **kwargs equivalent in Rust - rust

What is Python's *Args and **kwargs equivalent in Rust
def main(*args, **kwargs):
pass

Those are variadic arguments and Rust has no direct equivalent. This is because Rust is extremely strongly typed and must know exactly what types will be passed to a function.
Depending on what you're doing, you'd probably define a function that takes collections; Vec for *args and HashMap for **kwargs. But everything in each collection must be of the same type; a Vec of integers, a HashMap of pairs of strings, etc.

Related

Is there a Rust equivalent of R's mapply()?

What is the idiomatic Rust method for R's mapply()? mapply() takes a function, and iterables, and calls the function with the first elements of each iterable as arguments, the second elements, etc.
I am currently using the future_mapply() function in R from the future library to do it in parallel as well, but am finding it to be too slow.
Any help is appreciated.
There is no direct equivalent, as Rust doesn't deal with variadic functions or abstract over tuples of different lengths (better to ignore HLists here). If your number of iterators is fixed, you can use it1.zip(it2).zip(it3).map(|((e1, e2), e3)| f(e1, e2, e3)) or itertools::izip!.
If all your iterators have the same type (i.e. can be put into a Vec) and the function to be applied is fine with receiving the elements as a Vec, you could do something like
std::iter::from_fn(move || {
iter_vec // the vector with your input iterators
.iter_mut()
.map(Iterator::next)
.collect::<Option<Vec<_>>>()
}).map(f)
Playground
I think you'll have to describe your problem a bit more for your question to be properly answered.

When is it useful to use `ref` with a function paramter

This question is not about the difference between fn foo(x: &T) and fn foo(ref x: T).
I wish to ask when it's desirable / idiomatically correct to use the latter. I'm unable to imagine a scenario you would need the ref keyword in a function signature because you could just declare fn foo(x: T) and use &x inside the function.
At the top level of a function parameter list, there is no reasonable use case for ref. It basically results in ownership of the value being moved into the function, but you only get a reference to work with.
The reason this is allowed in a function parameter list is consistency with the pattern matching syntax in other parts of the language. You can use any irrefutable pattern as a function parameter, just like in let statements. Syntax and semantics of these assignments are essentially the same, but not everything that's technically allowed to be in a function parameter list actually makes sense there, just as not all code that compiles is actually useful. Clippy warns against using ref at the top level of a function parameter list.
It may be useful to use ref in destructuring in a function parameter list. If you accept, say, a reference to a pair &(String, String), and you want to give individual names to the to the two entries, you can use
fn foo(&(ref x, ref y): &(String, String))
to achieve this. Not using ref here would be invalid, since you can't take ownership of these strings.
Since the arrival of match ergonomics, this (and most other) uses of the ref keyword can be rewritten using the more succinct syntax
fn foo((x, y): &(String, String))
I personally prefer the longer, more explicit version, since the "ergonomic" version makes the types that x and y have more opaque.

What is the meaning of -> List[int] in this function declaration? [duplicate]

This question already has answers here:
What does -> mean in Python function definitions?
(11 answers)
Closed 1 year ago.
I want to understand the declaration of this function: ->List[int]:
I have learned the basics of Python and I never saw function declaration like this before
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
It is a so called "type hint" (or "function annotation"; these are available since Python 3.0).
-> List[int] means that the function should return a list of integers.
nums: List[int], target: int means that nums is expected to be a list of integers and that target is expected to be an integer.
This is not a hard requirement, though, i.e. you can still call the function with objects of different types passed for these parameters and the function can as well return something different than a list of intergers (unlike in other languages like Java where providing wrong types would result in a compile error). To put it differently: Type hints are irrelevant for the program execution, they are ignored at runtime (ignoring the type hints is just the default behavior, but they are available at runtime via __annotations__, so you could do something with them).
Type hints can express the intent of the author and can be checked before program execution by tools like mypy (these can check e.g. that a function is only called with parameters of the correct type and returns something of the correct type).
Note that List is not available in the standard namespace (unlike list), but (at least before Python 3.9) instead needs to be imported from typing which also
provides other types for standard types, like Set, Dict, Tuple, Callable etc.
allows to define own types
provides typed versions of other types, like NamedTuple instead of namedtuple
From Python 3.9 on, one could as well use the standard list constructor for the type hint, see here.
It's a new feature in version 3.5. You can see the docs.
https://docs.python.org/3.5/library/typing.html

Reasons for Dot Notation for Tuple

Is there any technical reason Rust is designed to use dot notation for tuples instead of using index notation (t[2])?
let t = (20u32, true, 'b')
t.2 // -> 'b'
Dot notation seems natural in accessing struct's and object's properties. I couldn't find a resource or explanation online.
I had no part in the design decisions, but here's my perspective:
Tuples contain mixed types. That is, the property type_of(t[i]) == type_of(t[j]) cannot be guaranteed.
However, conventional indexing works on the premise that the i in t[i] need not be a compile-time constant, which in turn means that the type of t[i] needs to be uniform for all possible i. This is true in all other rust collections that implement indexing. Specifically, rust types are made indexable through implementing the Index trait, defined as below:
pub trait Index<Idx> where Idx: ?Sized {
type Output: ?Sized;
fn index(&'a self, index: Idx) -> &'a Self::Output;
}
So if you wanted a tuple to implement indexing, what type should Self::Output be? The only way to pull this off would be to make Self::Output an enum, which means that element accesses would have to be wrapped around a useless match t[i] clause (or something similar) on the programmer's side, and you'll be catching type errors at runtime instead of compile-time.
Furthermore, you now have to implement bounds-checking, which is again a runtime error, unless you're clever in your tuple implementation.
You could bypass these issues by requiring that the index by a compile-time constant, but at that point tuple item accesses are pretending to behave like a normal index operation while actually behaving inconsistently with respect to all other rust containers, and there's nothing good about that.
This decision was made in RFC 184. The Motivation section has details:
Right now accessing fields of tuples and tuple structs is incredibly painful—one must rely on pattern-matching alone to extract values. This became such a problem that twelve traits were created in the standard library (core::tuple::Tuple*) to make tuple value accesses easier, adding .valN(), .refN(), and .mutN() methods to help this. But this is not a very nice solution—it requires the traits to be implemented in the standard library, not the language, and for those traits to be imported on use. On the whole this is not a problem, because most of the time std::prelude::* is imported, but this is still a hack which is not a real solution to the problem at hand. It also only supports tuples of length up to twelve, which is normally not a problem but emphasises how bad the current situation is.
The discussion in the associated pull request is also useful.
The reason for using t.2 syntax instead of t[2] is best explained in this comment:
Indexing syntax everywhere else has a consistent type, but a tuple is heterogenous so a[0] and a[1] would have different types.
I want to provide an answer from my experience using a functional language (Ocaml) for the while since I've posted this question.
Apart from #rom1v reference, indexing syntax like a[0] everywhere else also used in some kind of sequence structure, of which tuples aren't. In Ocaml, for instance, a tuple (1, "one") is said to have type int * string, which conforms to the Cartesian product in mathematics (i.e., the plane is R^2 = R * R). Plus, accessing a tuple by nth index is considered unidiomatic.
Due to its polymorphic nature, a tuple can almost be thought of as a record / object, which often prefer dot notation like a.fieldName as a convention to access its field (except in language like Javascript, which treats objects like dictionaries and allows string literal access like a["fieldname"]. The only language I'm aware of that's using indexing syntax to access a field is Lua.
Personally, I think syntax like a.(0) tends to look better than a.0, but this may be intentionally (or not) awkward considering in most functional languages it is ideal to pattern-match a tuple instead of accessing it by its index. Since Rust is also imperative, syntax like a.10 can be a good reminder to pattern-match or "go use a struct" already.

In Rust, what is the idiomatic equivalent of Haskell's [n..m]? [duplicate]

This question already has answers here:
How do I include the end value in a range?
(2 answers)
Closed 4 years ago.
How do I produce a list containing all the integers in Rust? I'm looking for the equivalent of Haskell's [n..m] or Python's range(n, m+1) but can't find anything.
I'm aware of the int::range function and thought it was what I was looking for, but it is made to iterate over a range, not to produce it.
It is now possible to use ..= in Rust:
let vec: Vec<_> = (n ..= m).collect();
gives you a Vec from all the numbers from n to m.
..= is the inclusive range operator, whereas .. is exclusive.
Note that this answer pertains to a pre-1.0 version of Rust and does not apply for 1.0. Specifically, Vec::from_fn was removed.
There's probably nothing really idiomatic as of now. There is a handful of convenience functions to construct vectors, for example you can use Vec::from_fn:
Vec::from_fn(m+1-n, |i| i+n)
Note that this answer pertains to a pre-1.0 version of Rust and does not apply for 1.0. Specifically, std::iter::range and std::iter::range_inclusive were removed.
As of Rust 1.0.0-alpha, the easiest way to accomplish this is to use the convenience functions provided in the module std::iter: range and range_inclusive, which return iterators generating a list of numbers in the range [low, high) or [low, high], respectively.
In addition, you can build a vector from an iterator using the collect method:
use std::iter::range_inclusive;
let first_hundred: Vec<i32> = range_inclusive(1, 100).collect();
println!("upper bound inclusive: {:?}, exclusive: {:?}",
first_hundred,
range(101, 201).collect::<Vec<_>>());
Note that the return value of collect has its type explicitly specified in both its uses above. Normally, the Rust compiler can infer the types of expressions without an explicit specification, but collect is one of the most common cases for which the type cannot be fully inferred, in this case because it can't infer a concrete type that implements the trait FromIterator<A>, the return type of collect.
The type of a generic return value can be specified either as an explicit type in a let definition statement or inline by using the function::<Type>() syntax. Since inference fails only due to not knowing a concrete type implementing FromIterator<A>, it's possible, when explicitly specifying a generic type, to leave "holes" for type arguments which will be inferred, signified by _. This is done with the second call to collect above—in the expression Vec<_>, it's explicitly specified that the container receiving elements from collect is a Vec<T>, but the compiler figures out what exact type T must be. Currently, integers whose types are left unspecified and can't be inferred fall back to i32 (32-bit machine integer) as a default.
Since Rust 1.26.0 you can use the RangeToInclusive (..=) operator to generate an inclusive range.
let v: Vec<_> = (n..=m).collect()

Resources