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

Language feature: flat tuple as function arguments #2667

Closed
swfsql opened this issue Mar 27, 2019 · 1 comment
Closed

Language feature: flat tuple as function arguments #2667

swfsql opened this issue Mar 27, 2019 · 1 comment
Labels
A-tuples Proposals relating to tuples. T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@swfsql
Copy link

swfsql commented Mar 27, 2019

Optionally flatten a tuple as arguments themselves when fed into a function.

This suggestion is tangent to other two suggestions:

So, for examaple:

fn some_fn(a: A, b: B) -> () {
  // ()
} 

let tuple = (A, B);
some_fn(tuple);

And:

(0..10)
  .map(|_| (A, B))
  .map(some_fn)
  .collect::<Vec<_>>();

would be possible/accepted.


I'm not sure if this could be reached with generics or some other way, but I believe it cannot.

The closest I could get with generics was:

struct A;
struct B;

fn call1<F, T1, FR>(tuple: (F, T1,)) -> FR
    where F: FnOnce(T1) -> FR {
    let function = tuple.0;
    function(tuple.1)
}

fn call2<F, T1, T2, FR>(tuple: (F, T1, T2)) -> FR
    where F: FnOnce(T1, T2) -> FR {
    let function = tuple.0;
    function(tuple.1, tuple.2)
}

fn some_fn(_a: A, _b: B) -> () {
    println!("hi");
    ()
}

fn main() -> () {

    let tuple = (A, B);
    some_fn(tuple.0, tuple.1);
    
    (0..2)
        .map(|_| (some_fn, A, B))
        .map(call2)
        .collect::<Vec<_>>();
}

But it would require inserting the function into the tuple beforehand, calling a call function (and also call the right one).. which is quite off from this feature request.


Another approach would be to wrap the original function, unflattening it:

// ...

fn some_fn_unflat((a, b): (A, B)) -> () {
    some_fn(a, b)
}

fn main() -> () {
    let tuple = (A, B);
    some_fn(tuple.0, tuple.1);
    
    (0..2)
        .map(|_| (A, B))
        .map(some_fn_unflat)
        .collect::<Vec<_>>();
}

Which is quite approachable. I originally didn't think about this, a macro could generate those wrapped functions.

I guess I'll be closing then lol sorry - but if someone would consider it to be appropriate as a standard approach, please feel free to reopen it :P

@Centril Centril added T-lang Relevant to the language team, which will review and decide on the RFC. A-tuples Proposals relating to tuples. labels Mar 27, 2019
@swfsql swfsql closed this as completed Mar 27, 2019
@swfsql
Copy link
Author

swfsql commented Apr 7, 2019

If anyone is interested,
I've uploaded an initial crate with the mentioned syntax:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tuples Proposals relating to tuples. T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

2 participants