Is there a reason why we cannot have syntactic sugar around tuples?

What I would like to see in C # is better syntax around tuples, for example.

var rgb = (1.0f, 1.0f, 1.0f); // Inferred to be Tuple<float, float, float> // Translated to var rgb = Tuple.Create(1.0f, 1.0f, 1.0f) 

AND

 var x, y, z = rgb; // Translated to: // float x = rgb.Item1; // float y = rgb.Item2; // float z = rgb.Item3; 

Is there anything in C # that prohibits this, or makes it too difficult / unrealistic to achieve? Perhaps there are other linguistic features that are directly related to this?

Please note that I am not asking if this is on the Microsoft radar or even if it matches their vision for C #, simply if there are any obvious blockers in theory.

Edit Here are some examples from other CLI languages

 // Nemerle - will use a tuple type from a language specific runtime library def colour = (0.5f, 0.5f, 1.0f); def (r, g, b) = colour; // F# - Will use either a library type or `System.Tuple` depending on the framework version. let colour = (0.5f, 0.5f, 1.0f) let (r, g, b) = colour // Boo - uses CLI array def colour = (0.5, 0.5, 1.0) def r, g, b = colour // Cobra - uses CLI array var colour = (0.5, 0.5, 1.0) var r, g, b = colour 

Although using arrays may seem like a good compromise, it becomes restrictive, for example, when mixing types. let a, b = (1, "one") F # or Nemerle will give us Tuple<int, string> . In Boo or Cobra, this will give us object[] .

Edit2 Language support for tuples added in C # 7 - https://www.kenneth-truyers.net/2016/01/20/new-features-in-c-sharp-7/

+6
source share
3 answers

The second syntax was shown to be impracticable by Tigran and Hilgart.

Check out the first syntax:

 var rgb = (1.0f, 1.0f, 1.0f); 

What happens if you do not want to use the Tuple class because instead you want to use the MyTuple class (which may have the advantage of IEnumerable<object> , something very useful!)? Obviously, the syntax will not help. You would need to put the MyTuple class somewhere ...

 MyTuple<float, float, float> rgb = (1.0f, 1.0f, 1.0f); 

or

 var rgb = new MyTuple<float, float, float>(1.0f, 1.0f, 1.0f); 

now the advantage of this new shorthand syntax is no longer because somewhere you should put MyTuple<float, float, float> .

Note that there is no collection initializer that simply "automatically detects" everything.

 var myVar = new List<int> { 1, 2, 3 }; 

Here the fact that we are talking about a List<int> is perfectly clear :-)

Even an array initializer that is a bit "special" is not implicit ...

 int[] myVar = { 1, 2, 3 }; var myVar = new[] { 1, 2, 3 }; var myVar = new int[] { 1, 2, 3 }; 

all are valid, but the fact that we're talking about an array is always explicit (there is always [] )

 var myVar = { 1, 2, 3 }; 

invalid :-) And the array has an β€œadvantage” as a primitive construct (arrays are supported directly by the IL language, and all other collections are built on top of other .NET libraries and / or arrays)

+1
source

This is clearly a design problem, because in your case you only assign the value to the last variable, where the other two take default values ​​of the specified type.

 var x, y, z = rgb; 

Thus, regardless of rgb , only z is assigned to it. If you change this behavior, it would be completely unclear what happens to this line:

  • assignment of the whole variable
  • assignment only for the last

If you don’t make a clear decision here, this will lead to different types of behavior based on the type on the right side of the assignment operator: in one case it will be a declaration and assignment of a default value, in the other case a declaration and assignment of a specific value.

+3
source

The second option is impossible, because it already means something else:

 float x, y, z = 0.1f; 

This declares three variables x , y and z with initialization z to 0.1 . The difference with the syntax suggested in your question is subtle at best.

+2
source

Source: https://habr.com/ru/post/953561/


All Articles