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

Implement Varargs #1

Merged
merged 2 commits into from
Sep 12, 2019
Merged

Implement Varargs #1

merged 2 commits into from
Sep 12, 2019

Conversation

fcard
Copy link
Owner

@fcard fcard commented Sep 12, 2019

This adds the special Vararg! "macro" (really just a marker) which allows the creation of variadic methods, i.e. methods that take a variable number of arguments. The "vararg" variable collects the optional arguments in a Vararg<T> type, which implements IntoIterator as a value, a reference and a mutable reference, as well as Index and IndexMut for SliceIndex<[T]> (making it sort of like a fixed-length vector)

Example:

multifunction! {
  fn MAX(args: Vararg![i32]) -> Option<i32> {
    args.iter().max().map(|x| *x)
  }
}

fn main() {
  println!("{:?}", MAX(1,2,3)); // Some(3)
  println!("{:?}", MAX(1));     // Some(1)
  println!("{:?}", MAX());      // None
}

This is a pretty silly implementation, since it just adds a method for each possible number of extra arguments, e.g. the MAX function above has 13 methods, one for zero, another for one, another for two.. until twelve. Since method can only have up to 12 arguments currently, the total number of methods is (13 - the number of required arguments). This will have to do until Variadic Generics are implemented. (rust-lang/rfcs#376, rust-lang/rfcs#1935)

Also of note is the interaction between varargs and other methods.

multifunction! {
  fn F(args: Vararg![]) {
    println!("Least specific")
  }

  fn F(arg: Abstract![ANY], args: Vararg![]) {
    println!("Middling")
  }

  fn F(arg: i32, args: Vararg![]) {
    println!("Most specific")
  }
}

fn main() {
  F();     // Least specific
  F("a");  // Middling
  F(1i32); // Most Specific
}

  Instead of using tuples of TypeIds/TypeMatches, use dedicated enums
this will facilitate having more than 12 arguments per method, as the
main reason that limitation was in place was because the Hash impl for
tuples only went as far as 12 elements.
  The TypeMatches enum also has variants signifying it contains a vararg
which is the first step for supporting them.
@fcard fcard merged commit 66aa702 into master Sep 12, 2019
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.

1 participant