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

Proposal: Return type inference for upcoming tuples proposal - syntactic sugar #5161

Closed
iam3yal opened this issue Sep 11, 2015 · 7 comments
Closed

Comments

@iam3yal
Copy link

iam3yal commented Sep 11, 2015

So it seems like the direction is heading towards named tuples
which at first I didn't like very much but then after some thoughts and reading,
I can see how it's better in some ways than positional tuples.

One of the issues I have with named tuples is mostly an aesthetics problem of looking at the source code,
it would feel like looking at a train of information if we have like more than 3 fields on the tuple and what I mean by that is currently we can declare a list of generic arguments and a list of parameters at the method level.

Now, add a list of tuples and you won't be able to see the forest for the trees when looking at some methods, some people might say, yeah but you can always use a class or a struct but then again sometimes it isn't desirable or reasonable because sometimes you just want to return this data structure specifically for this one method, after all it's one of the reasons for having tuples.

So I propose the following syntactic syntax:

public (sum, count) Tally(IEnumerable<int> values) 
{
    // ...

    return (s, c);
}

Or

public var (sum, count) Tally(IEnumerable<int> values) 
{
    // ...

    return (s, c);
}

The biggest challenge here and admittedly I didn't think about it at first when I posted it at #347 but @aluanhaddad enlightened me, anyhow, how do you infer the type when the method body isn't available to the consuming code?

Would it help if the compiler generated an attribute that would specify the types? like so.

[TupleReturnTypes(typeof(int), typeof(int))]
public (sum, count) Tally(IEnumerable<int> values) 
{
    // ...

    return (s, c);
}
@iam3yal iam3yal changed the title Proposal: Return type inference for upcoming tuples proposal Proposal: Return type inference for upcoming tuples proposal - syntactic sugar Sep 11, 2015
@HaloFour
Copy link

The compiler would be emitting the method with a concrete return type either way so there is no need for an attribute, at least not for the types. One would be required for the names. The return type would be ValueTuple<int, int> or whatever the name will end up being for the struct tuple types.

This proposal would seem to be in the same vein as #17 to allow type inference for return types of methods in general.

@iam3yal
Copy link
Author

iam3yal commented Sep 11, 2015

@HaloFour yeah, well, it might seems like #17 but it's quite different in a sense, I'm not asking to infer everything I'm asking to reduce the noise out of the method, I don't want to have aggressive type inference but when it make sense, I think it can help at least in the context of tuples.

We're moving from polluting the source code with classes/strucs that don't fits into the domain of the software where one of the solutions to this problem is tuples into polluting the methods with data that while relevant can make it really hard to grasp when it comes down to readability, so readability is my main concern here.

There might be better ways to do it but I really think they should take this into consideration.

@HaloFour
Copy link

I don't see why it would be different. If anything being less universal makes less sense. Either way you're requiring the compiler to infer the return type which then becomes part of the contract for the method. The same arguments for/against would apply.

@iam3yal
Copy link
Author

iam3yal commented Sep 11, 2015

@HaloFour well I guess we will have to keep that balance between maintainability and readability when it comes down to tuples.

Having too many fields on the tuple itself reduces readability whereas having too many classes/structs that polluting the domain can increase maintainability especially in big projects, so a tradeoff exists but I don't know whether aesthetics should be the reason for this tradeoff, in fact I don't think that there should be a tradeoff at all.

In my mind I'd want to use tuples when I'd want to return multiple values and not be concerned in the amount of values I'd return just because it makes things verbose and reduces readability.

In my opinion the question that a developer should ask when he/she wants to use tuples is whether there's some reusable concept to model that is shared in the domain followed by another question that is whether it needs to be exposed externally? such as having public APIs.

Here is a simple truth table.

reusable concept exposed externally tuples
F F T
F T F
T F F
T T F

@gafter
Copy link
Member

gafter commented Sep 12, 2015

I don't understand how you propose the compiler infer the return type. I'm imagining a scenario where you have a set of mutually recursive methods all calling each other... how is the compiler supposed to figure out any of the types? If it is an error, where is the compiler supposed to point the programmer to as the place to fix it?

@iam3yal
Copy link
Author

iam3yal commented Sep 12, 2015

@gafter, well, at first I thought it's possible to get the information from the method's body, meaning, get the types from from the point where they are known inside the method's body and then embed them either through attributes or directly on the method when the IL is generated.

I'm not really a compiler guy by heart but yeah that was kinda my thoughts.

If it's not possible there's another approach that I thought of, that can reduce the noise.

public (int sum, count, string name, desc) Tally(IEnumerable<int> values) 
{
    // ...

    return (s, c, b, d);
}

So in this approach we declare the type once per field and if we need the same type for the next field we can omit it until we need a new type.

So this is equivalent to the following method.

public (int sum, int count, string name, string desc) Tally(IEnumerable<int> values) 
{
    // ...

    return (s, c, b, d);
}

All I'm asking is syntactic sugar that makes sense, if it doesn't make sense that's fine, I hope that more people will chime in and share their own ideas for it.

@iam3yal
Copy link
Author

iam3yal commented Sep 12, 2015

@gafter, Forgot to mention that there's a clearly an issue with recursions, I didn't think that through.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants