Replies: 12 comments
-
I like the symmetry with parameters and argument lists. |
Beta Was this translation helpful? Give feedback.
-
I assume that you also intend that the compiler could convert tuples with fewer elements into the return type filling in the missing elements? private (string always1, string always2, bool rare = false) Method() {
var tuple =("a", "b");
return tuple; // converted into return (tuple.Item1, tuple.Item2, false);
}
Yes, and honestly that's my problem with this proposal. Tuples took a very big turn away from how parameter lists behave when the LDM decided that ordinal mattered more than name and I think that would be a big cause of confusion. public (int x = 0, int y = 0, int z = 0) GetPoint3D() {
return (z: 5, y: 10);
}
var p3d = GetPoint3D();
Debug.Assert(p3d.x == 5);
Debug.Assert(p3d.y == 10);
Debug.Assert(p3d.z == 0); |
Beta Was this translation helpful? Give feedback.
-
@HaloFour While it's true that that would be a problem, it's also something where the compiler could produce a warning. And in similar situations, it already does. This code: public (int x, int y) GetPoint3D() {
return (y: 5, x: 10);
} produces:
Or do you think a warning would not be enough? |
Beta Was this translation helpful? Give feedback.
-
The warning might be enough, but I still think that the behavior is confusing and the warning might be overlooked. It's a shame that the LDM chose to go this route rather than reordering the assignment of named tuples in these kinds of cases unlike what Apple did with Swift (in some cases, anyway). It was the one big area where tuples and parameter lists differed in behavior. |
Beta Was this translation helpful? Give feedback.
-
@HaloFour I think the reason is the whole philosophy that tuple names are syntax sugar only and have no semantic meaning. It's unfortunate but the warning + squiggle is probably enough. The usefulness of this proposal seems extremely limited. It would only be helpful in cases where the method has multiple return statements (otherwise what's the point of not just writing your default value in line with the return statement?) And I think having the compiler silently re-write return values needs a very high bar of usefulness. |
Beta Was this translation helpful? Give feedback.
-
private (string always1, string always2, bool rare) Method()
{
(string, string, bool) _(string always1, string always2) => (always1, always2, false);
if (...) return _("a", "b");
if (...) return _("c", "d");
if (...) return _("e", "f");
if (...) return _("g", "h");
if (...) return ("i", "j", true);
// ...
} (though I'd give Seems a good enough solution to me, without changing the language and cluttering up the signature with implementation details. |
Beta Was this translation helpful? Give feedback.
-
@DavidArno I don't think that this is a "solution", if anything I'd say it's a workaround because you need to duplicate the same thing over and over when you need it and I think that these kind of local methods can get in the way, however, I'll admit, I didn't yet need for such a feature but nonetheless, I think it's a nice to have.
The exact same thing can be said about optional arguments only today we have them in the language. I rather have my signature cluttered and well documented then having redundant local methods where the more optional elements you have the harder is to come with a self-explanatory name.
|
Beta Was this translation helpful? Give feedback.
-
If I have a method, void Foo(string a, string b, bool c = false) => ... I'm providing the caller with a contract; I'm saying they can skip If though I have a method, (string a, string b, bool c = false) Foo() => ... The contract is that I'll return a Further, what then happens with interfaces, especially with default implementations? I might have the following in an interface: (string a, string b, bool c = false) Foo() => ("", ""); But in a class, I might want interface A
{
string Foo(string a = "a");
}
class B : A
{
public string Foo(string a = "b") => a;
}
A b = new B();
var x = b.Foo(); // x is "a" So would we have the same behaviour here: Interface A
{
(string s1, string s2, bool b = false) Foo() => ("", "");
}
class B : A
{
(string s1, string s2, bool b = true) Foo() => ("", "");
}
A b = new B();
var x = b.Foo();
// is x ("", "", false) or ("", "", true) here? |
Beta Was this translation helpful? Give feedback.
-
This depends on how this is implemented. Return types might not emit any attribute at all and just help the compiler within the method scope, while for parameter like
If the default is not emitted for the return values (and I don't see a reason to), then the implementing method would always be able to define different defaults. If the default is inside the parameter type -- same rules as with parameter defaults. |
Beta Was this translation helpful? Give feedback.
-
@DavidArno I see what you mean now and I agree.
The issue is people might expect to have the ability to skip optional elements at the call site or at the point of deconstruction like so |
Beta Was this translation helpful? Give feedback.
-
@DavidArno I think it could behave just like the |
Beta Was this translation helpful? Give feedback.
-
Any update on this? It would be really useful when returning a tuple in an |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I feel it would be nice to be able to specify default values for tuple elements (with same restrictions as on default values on method parameters). The purpose is to allow the compiler to cast a smaller tuple to a larger one by filling in the remaining values.
Example:
Beta Was this translation helpful? Give feedback.
All reactions