Skip to content

Reconsider recommended casing/naming for tuple members in corefx. #27939

@CyrusNajmabadi

Description

@CyrusNajmabadi

dotnet/corefx#26582 Added a new 'Zip' extension for IEnumerables with teh following signature:

public static IEnumerable<(TFirst First,TSecond Second)> Zip<TFirst, TSecond>(
    this IEnumerable<TFirst> first, IEnumerable<TSecond> second)

The capitalization of the tuple members names (i.e. First/Second) was somewhat surprising to me as that wasn't the naming pattern that I thought we generally followed when creating and presenting tuples, and was not the naming pattern we've used in dotnet/roslyn itself.

The intuition here was that tuples very commonly act as a shorthand way to bundle lightweight data together so they can easily be grouped and passed in and out of methods without hte heavyweight need to define an entire struct (and all the rest of the ceremony you would need there).

This naturally leads to two reasonable interpretations of things that could influence naming decisions:

  1. this is just a simpler way of dealing with a named struct. These are fields, and as such should likely be named similar to public mutable fields/properties (so presumably PascalCased).
  2. these are a collection of parameters. The tuple itself is intended to fade out of the way, and people will most naturally think of working with these as a bunch of parameters/locals. As such, they should be named similar (so presumably camelCased).

IMO, from my recollection of the design here in the LDM, we'd been pushing harder on the second position. We've put a lot of effort into making it feel very natural to just 'splat/deconstruct' tuples, pushing the positoin more that the tuple is less relevant, and it's just a bundle of variables you'll be working with locally in your methods. While it's true that that doesn't necessarily mean the tuple field names have to match the expected usage names, it feels unfortunate that these names would now have to differ in case. This goes for both consumption, where field names are being splatted into different local names, as well as construction. It's extremely natural for someone to just construct a tuple like so: (name, age), but this would, for example, now create a tuple with names that don't actually match a method that returns something like (string Name, int Age). This lack of symmetry obviously is not a problem in terms of compilation (the language allows and converts here). However, it feels problematic to me because the code is now no longer working consistently with the same names that flow in, get worked on, and flow out.

This is not a huge deal. But i think it warrants discussion as any decision made here will effectively impact all future usages of tuples across our APIs and our customers' APIs.

Thanks very much.

--

Note: additional data points. Both swift and go allow one to return multiple named values from a method/function. In both those cases, naming of those multiple-named values matches parameter naming.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions