Variadic generics design sketch

I've tweaked how ref and ref mut work with ... patterns. ...ref ident and ...ref mut ident are now supported for arrays; placing the keywords after the ellipsis means you bind a reference to an array, while placing them before it means you bind a collection of references.

With this change, I think I am fully satisfied with the design of ... patterns and the ... operator.

I think I would have expected the opposite: ref ...arr doesn't quite make sense to my eyes since ref applies to bindings and ...arr isn't a binding, but if I had to give it a meaning it is like applying & to the ...arr pack, meaning we want to take a reference to the array(?) instead of just getting the array itself, while ...ref arr looks like a C++ pack expression or macro_rules $($arr)* binding, you get a sequence of ref arr bindings, i.e. a pack of references.

I would be a bit wary of making the "reference to array" meaning legal, however you spell it, because if it's a pack from a tuple or tuple struct then you most likely can't acquire such a reference, and if it's an array then there are already alternative spellings to get that reference.

How I think of it: in ...ref arr, the ref applies directly to the value bound by arr, which is an array. Hence, a reference to an array. In ref ...arr, the ref applies "before" the comma-separated list is collected into an array (or "after" it is expanded from one), so references are taken elementwise.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

I don't think I've seen it mentioned here but I wanted to bring up a use case that is important to me. I think variadics should have good support for #[cfg] attributes to toggle their members, for example:

type MySoA = VariadicSoa<
    TypeA,
    TypeB,
    #[cfg(feature = "extras")]
    TypeC,
>;

It seems like that would be well supported in general but it would need to be accounted for in the grammar. Currently there are multiple positions in the language where #[cfg] has been overlooked.

2 Likes

I honestly think if we are going with the ... operator in the declaration then this should be the syntax.

Example of a function that uses a variadic generics

fn make_tuple<Ts...>(val: Ts...) -> (Ts...) { }

where the function declaration above reads as follows:

  • a function named make_tuple with a variadic generic type of type Ts and others
  • parameter val which is of type Ts and other types
  • return type is a tuple of type Ts and others.

Usage

let tuple_of_str_int_float: (&str, i64, f64) = make_tuple("str val", 23, 4.5);

IMO this improves readability for both the code writers aka library authors and code consumers ie library users

This could be worked around this way, so I don't think that it should be a priority.

#[cfg(not(feature = "extras"))]
type MySoA = VariadicSoa<
    TypeA,
    TypeB,
>;

#[cfg(feature = "extras")]
type MySoA = VariadicSoa<
    TypeA,
    TypeB,
    TypeC,
>;

It could, but it doesn't scale well to multiple #[cfg] cases.

#[cfg(all(not(feature = "first"), not(feature = "second")))]
type MySoA = VariadicSoa<
    TypeA,
    TypeB,
    TypeC,
    TypeD,
>;

#[cfg(all(feature = "first", not(feature = "second")))]
type MySoA = VariadicSoa<
    TypeA,
    TypeB,
    TypeC,
    TypeD,
    TypeE,
>;

#[cfg(all(not(feature = "first"), feature = "second"))]
type MySoA = VariadicSoa<
    TypeA,
    TypeB,
    TypeC,
    TypeD,
    TypeF,
>;

#[cfg(all(feature = "first", feature = "second"))]
type MySoA = VariadicSoa<
    TypeA,
    TypeB,
    TypeC,
    TypeD,
    TypeE,
    TypeF,
>;

It would certainly preferable to be able to do

type MySoA = VariadicSoa<
    TypeA,
    TypeB,
    TypeC,
    TypeD,
    #[cfg(feature = "first")] TypeE,
    #[cfg(feature = "second")] TypeF,
>;

This can already be done with non-variadic types, I just want to make sure it's accounted for in the grammar for variadics as well. There are a handful of lexical positions where #[cfg] isn't allowed largely out of oversight, and probably should be permitted -- RFC 3399 is one such example.

I don't foresee any issues here.


I've expanded the HackMD's section on recursion, incorporating some insights from A madman's guide to variadic generics.

2 Likes