I suggest you ...

Return Multiple values from functions effortlessly without creating new classes for everything

When you think of it, its silly that methods by default can only return one value, but can take many arguments. Often times you want many return values, but it would be too painful to create classes/structs for each set, so often developers decide to then use ref or out parameters.

Instead what if method/function calls could return many values without the need to define a class/struct.
This example is a bit contrived but this shows the power of the fact that error information and values can easily be returned al at once.

Syntaxt like:

private {int index, bool IsError=false, string errorMsg=null} FindStringIndex(string[] strings, string stringToFind)
{

for (int x=0; x<strings.Length; x++)
{
if (strings[x]==stringToFind)
return x;

}

return {-1,true,"String not found"}

}

Usage:

string[] mystrings={"One","Two","Three"};

var val=FindStringIndex(mystrings,"Three");

if (!val.IsError)
Console.Writeline("Found index {0}",val.index);

Alternate usage (works like it doesn't even have those extra parameters but can easilyy access when you need them.:

int! index=FindStringIndex(mystrings,"Three");

if (index==-1)
{
if (index.IsError)
Console.Writeline("Error:",index.errorMsg);

}

The ! like a ? changes the int into sort of a template object, but this one allows access to the named values returned from a method. The first return value is the default but using a default keyword can change that. The default value would be the one default returned.

Alternate usage#2:
string {errormsg} msg=FindStringIndex(mystrings,"Three");

(Not very useful but this using the name of the return value pulls just the value it needs.

Alternate usage#3:
string {string} msg=FindStringIndex(mystrings,"Three");

Retrieves the one string in the return values by type rather than by name.

Personally I don't like this syntax exactly but basically looking for some way to be able to easily return multiple values from a function call without having to create more classes/structs.

114 votes
Vote
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    I agree to the terms of service
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    DaveDave shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

    17 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      I agree to the terms of service
      Signed in as (Sign out)
      Submitting...
      • A. de WinkelA. de Winkel commented  ·   ·  Flag as inappropriate

        looks to me more like a variable result function.
        var funcname(...)
        however mostly I encounter simply the need to overload a function with a known result type that differs from already existing while parameters remain the same. Now I need to change the name of the function while (in principle) the compiler could pick up the difference between pe:
        int myint = doSomething();
        string mystr = doSomething();
        (real encounters of course more complex) function bodies here differ, but I can see the possible.
        var myvar = doSomething()
        switch (myvar)
        {
        case typeof(int): ... break;
        case typeof(string): ... break;
        }
        however typeswitching is also not defined in C# (see connect item)

      • CarstenCarsten commented  ·   ·  Flag as inappropriate

        While it is correct to use Tuple<...> here, it does not meet the point of Dave's idea. Because Tuple<...> derives from System.Object, boxing and unboxing would pop up as soon as value types would be involved.

      • aajayaajay commented  ·   ·  Flag as inappropriate

        does not make sence can you provide a sample thanks

      • Michael BurbeaMichael Burbea commented  ·   ·  Flag as inappropriate

        I'd like it if it bound to a tuple automatically.
        But what I'd really like is comprehension on the callsite.
        e.g.
        int x,string foo = SomeMethodThatReturnsTuple();

        This could be really translate to
        Tuple<int,string> SomeMethodThatReturnsTuple();
        And the call site could be:
        var <holder>_callsite = SomeMethodThatReturnsTuple();
        int x = <holder>_callsite.Item1;
        string foo = <holder>_callsite.Item2;
        With "native" comprehension of tuples C# will be a lot friendlier.

      • BenjolBenjol commented  ·   ·  Flag as inappropriate

        Tuples are obviously the right way to do this, but I'm with gzak: some smart sugar would be an excellent idea: that way you can abstract away the implementation details and go straight to the point. Remains to be seen what the compiler team can come up with that won't break anything else, but they're a smart bunch.

        How about pattern matching, while we're at it? :)

      • gzakgzak commented  ·   ·  Flag as inappropriate

        whoops, the desugared return type should be Tuple < int, int > (tuple of two ints, but I think it's getting scraped out).

      • gzakgzak commented  ·   ·  Flag as inappropriate

        I would actually opt for some smart syntactic sugar around the Tuple<> type, something like this:

        private (int, int) myFun(int x, int y) { return (x+y, x*y); }

        and usage (always must be named):

        int sum; // can reuse existing variable
        (sum, prod) = myFun(3, 5); // or declare a new one? Maybe...

        And essentially all this is is syntactic sugar for:

        private Tuple<int, int> myFun(int x, int y) { return Tuple.Create(x+y, x*y); }

        and:

        int sum;
        var tuple = myFun(3, 5); // obviously "var tuple" would be some hidden compiler generated name
        sum = tuple.Item1; // reuse variable
        int prod = tuple.Item2; // create new variable

        Coupled with some way to document the various values in the returned tuple, I think this can go a long way to clean up some (really inelegant) "out" keyword usage, which is really just a vestige from days of yore.

      • RafeRafe commented  ·   ·  Flag as inappropriate

        I admit I haven't needed this due to out values, but out values aren't cross-language-available if I remember right (I work in an environment where this matters)

        I miss this from python. It would be like:
        public {string, int, int} DoSomething() {}

        usage:
        string s;
        int i
        int n
        s, i, n = DoSomething();

        or?
        string s, int i, int n = DoSomething();

        not the prettiest, but I don't think this collides with anything in C# now, does it?

      • DennisDennis commented  ·   ·  Flag as inappropriate

        Tuple<> really is the proper solution for this problem. I didn't really understand that until I started reading the book "Real-World Functional Programming." Try learning some F# if you want to get a better feel for using functions.

        F# actually translates .NET functions that have out params into tuple return values. It's very nice once you get used it.

      • DaveDave commented  ·   ·  Flag as inappropriate

        I agree the anonymous type would have been an interesting option to support this type of functionality. Though it would be good if the return information didn't require creating another class to be allocated. Might be better to act more like a value type returned to avoid extra object creations if possible by handling it in the compiler rather than runtime (I'm sure there has to be a bunch of thought on that to see if its do-able)

      • LMKLMK commented  ·   ·  Flag as inappropriate

        Shame you can't use an anonymous class as return type, as per previous commenter. The problem with tuples is that the various fields are unnamed, so the code is not as readable.

      • DaveDave commented  ·   ·  Flag as inappropriate

        The Tuple is an interesting workaround for this. It still involves another class overhead though it handles it for you. It is a good point templates can make this easier, though it would be nice if the language supported this as a core function to allow the returned values to be used a little easier.

      • DaveDave commented  ·   ·  Flag as inappropriate

        Out parameters are a bit of a kludge. People use those because they don't want to make a seperate class to return multiple values. Think about it, why must a function only return one value (unless I create my own class). Its really a relic to the way languages were created where functions just return a single value. Returning multiple makes my code cleaner, I don't need to create a seperate class just to return more than one value, I don't need to force people to pass extra parameters just because I was too lazy to create a class to allow me to return multiple values or incur the overhead of a class creation/heap.

      • DaveDave commented  ·   ·  Flag as inappropriate

        I'm sure there are cases where out parameter can make sense but often if a parameter is passed as an out parameter purely because you want to return another value, it really most of the time would be better if a function could return multiple values rather than requiring to use an out parameter. A class return value sometimes makes a lot of sense (often can be the right thing to do, but often is not done due to either the overhead for the programmer to create it, the additional clutter it would create, additional memory allocation it may take, etc.)

      • DennisDennis commented  ·   ·  Flag as inappropriate

        Isn't that what out parameters are for? Why are you creating "more classes/structs" to do this?

      • DaveDave commented  ·   ·  Flag as inappropriate

        Got cut off:
        When you think of it, its silly that methods by default can only return one value, but can take many arguments. Often times you want many return values, but it would be too painful to create classes/structs for each set, so often developers decide to then use ref or out parameters.

        Instead what if method/function calls could return many values without the need to define a class/struct.
        This example is a bit contrived but this shows the power of the fact that error information and values can easily be returned al at once.

        Syntaxt like:

        private {int index, bool IsError=false, string errorMsg=null} FindStringIndex(string[] strings, string stringToFind)
        {

        for (int x=0; x<strings.Length; x++)
        {
        if (strings[x]==stringToFind)
        return x;

        }

        return {-1,true,"String not found"}

        }

        Usage:

        string[] mystrings={"One","Two","Three"};

        var val=FindStringIndex(mystrings,"Three");

        if (!val.IsError)
        Console.Writeline("Found index {0}",val.index);

        Alternate usage (works like it doesn't even have those extra parameters but can easilyy access when you need them.:

        int! index=FindStringIndex(mystrings,"Three");

        if (index==-1)
        {
        if (index.IsError)
        Console.Writeline("Error:",index.errorMsg);

        }

        The ! like a ? changes the int into sort of a template object, but this one allows access to the named values returned from a method. The first return value is the default but using a default keyword can change that. The default value would be the one default returned.

        Alternate usage#2:
        string {errormsg} msg=FindStringIndex(mystrings,"Three");

        (Not very useful but this using the name of the return value pulls just the value it needs.

        Alternate usage#3:
        string {string} msg=FindStringIndex(mystrings,"Three");

        Retrieves the one string in the return values by type rather than by name.

        Personally I don't like this syntax exactly but basically looking for some way to be able to easily return multiple values from a function call without having to create more classes/structs.

      Feedback and Knowledge Base