What Requirement Was the Tuple Designed to Solve

What requirement was the tuple designed to solve?

When writing programs it is extremely common to want to logically group together a set of values which do not have sufficient commonality to justify making a class.

Many programming languages allow you to logically group together a set of otherwise unrelated values without creating a type in only one way:

void M(int foo, string bar, double blah)

Logically this is exactly the same as a method M that takes one argument which is a 3-tuple of int, string, double. But I hope you would not actually make:

class MArguments
{
public int Foo { get; private set; }
... etc

unless MArguments had some other meaning in the business logic.

The concept of "group together a bunch of otherwise unrelated data in some structure that is more lightweight than a class" is useful in many, many places, not just for formal parameter lists of methods. It's useful when a method has two things to return, or when you want to key a dictionary off of two data rather than one, and so on.

Languages like F# which support tuple types natively provide a great deal of flexibility to their users; they are an extremely useful set of data types. The BCL team decided to work with the F# team to standardize on one tuple type for the framework so that every language could benefit from them.

However, there is at this point no language support for tuples in C#. Tuples are just another data type like any other framework class; there's nothing special about them. We are considering adding better support for tuples in hypothetical future versions of C#. If anyone has any thoughts on what sort of features involving tuples you'd like to see, I'd be happy to pass them along to the design team. Realistic scenarios are more convincing than theoretical musings.

Is Using .NET 4.0 Tuples in my C# Code a Poor Design Decision?

Tuples are great if you control both creating and using them - you can maintain context, which is essential to understanding them.

On a public API, however, they are less effective. The consumer (not you) has to either guess or look up documentation, especially for things like Tuple<int, int>.

I would use them for private/internal members, but use result classes for public/protected members.

This answer also has some info.

Defining tuple methods

Yes, there is. Just define a new trait and implement it immediately, something like this:

trait Swap<U> {
fn swap(self) -> U;
}

impl<A, B> Swap<(B, A)> for (A, B) {
#[inline]
fn swap(self) -> (B, A) {
let (a, b) = self;
(b, a)
}
}

fn main() {
let t = (1u, 2u);
println!("{}", t.swap());
}

Note that in order to use this method you will have to import Swap trait into every module where you want to call the method.

When to use: Tuple vs Class in C# 7.0

As this answer is causing some confusion amongst some folk here, I should clarify that - as per the question - all references to "tuple" here refer to the ValueTuple type and new tuple syntactic sugar features of C# 7 and in no way refer to the old System.Tuple reference types.

So now I am wondering, when Should I use tuples and when Should I create a class in c# 7.0?

Only you can really answer that question as it really depends on your code.

However, there are guidelines and rules you can follow in guiding you in choosing between them:

Tuples are values, so are copied by value, rather than by reference.

Most of the time, this should not be an issue. However, if you are passing around tuples of large structs, this might have an impact on performance. Ref locals/returns can be used to work around these performance issues, though.

Additionally, because they are values, modifying a copy remotely will not change the original copy. This is a good thing, but could catch some folk out.

Tuple element names are not persisted

The names given to elements are used by the compiler and (in most cases) are not available at run-time. This means that reflection cannot be used to discover their names; they cannot be accessed dynamically and they cannot be used in razor views.

Also this is an important consideration with APIs. A tuple returned from a method is the exception to the rule regarding after-compilation name discoverability. The compiler adds attributes to the method that hold information on the tuple names. This means you can safely return a tuple from a public method in one assembly and access its names in another.

Tuples are lightweight

Tuples are much simpler to write than types as they are less verbose and the declaration can be "inlined" (ie declared at the point of use). This works well when declaring a method that returns multiple values, for example.

However, because they are declared at the point of use, if you have MethodA that calls MethodB that calls MethodC and each returns a tuple, you'll need to redefine the tuple at every stage. There isn't (yet) a way of creating an alias of a tuple and re-using it across multiple methods.

Just use common sense

For any situation where you might consider using a tuple: simply ask yourself the question: "will a tuple simplify the code here". If the answer is "yes", then use one. And that ultimately is the primary consideration over whether to use a tuple or a custom class.

Vaugue error TypeError: Tuple or struct_time argument required

I am not able to verify the cause of the error but the fetch() method was returning the flags of the email after it was recieved. To solve this I have changed the the lambda to a function as follows:

def latest_mail():
internal_date = imap.fetch(imap.search(None, "ALL")[1][0].split()[-1], "(INTERNALDATE)")[1][0]
return time.mktime(imaplib.Internaldate2tuple(internal_date)) if "INTERNALDATE" in internal_date.decode() else False

In the while loop I check if the return value is false, and if it is then I use the continue statement otherwise I proceed with the loop.

what tuples are good for?

Here are a few resources that mention the purposes of Tuples, how they can be used and what they can be used for:

The Practical Usage of Tuples in C#

Making Use of Tuples

Using Tuples in .NET 4.0 | Stack Overflow

Tuple Support in C# | Stack Overflow

Usages and Advantages of Tuples | DotNetSpeaks

Summary:

Basically, the Tuple functions as a convenient way to NOT make a custom class to accomplish something. It is highly flexible and could provide a variety of uses, however since it can be very generic, you should be sure to properly document its usage.

Real world and efficient example of solving a problem in C# using Tuple class

Tuple is said to have been introduced to .NET 4 because some programming languages (let's say, for example, IronPython or F#) support tuples as a core feature of the language, and the .NET BCL team wanted to provide a uniform tuple type for such languages (for language interoperability reasons, I guess):

The BCL team decided to work with the F# team to standardize on one tuple type for the framework so that every language could benefit from them. (in Eric Lippert's answer to the SO question, What problem was the tuple designed to solve?
)

Tuple does not make much sense in the C# language IMHO, because C# doesn't support tuples and some associated language constructs very well; e.g. tuple "explosion": spreading a tuple over a function's parameters, or taking a function's return values (in the form of a Tuple) and spreading it over several local variables:

Tuple<int,int>  GetFoo() { … }
// v v
int (a, b) = GetFoo(); // C# doesn't support this tuple-related syntax.

That being said, if you're writing only C# code, you can usually find "better", more structured solutions than using Tuple. For example, using tuples to return more than one value from a method (such as in GetFoo above) is quick and convenient, but the return value doesn't have any inherent structure — you might do better with a struct or class type, if you're willing to take some additional time to define it.



Related Topics



Leave a reply



Submit