Skip to content

Conversation

@BillWagner
Copy link
Member

@BillWagner BillWagner commented May 15, 2018

Add add the UDT equality example
@BillWagner BillWagner requested review from mairaw and rpetrusha May 15, 2018 14:40
@BillWagner
Copy link
Member Author

closing and reopening for a new build.

@BillWagner BillWagner closed this May 15, 2018
@BillWagner BillWagner reopened this May 15, 2018
consistent rules for copies and assignments. As a tradeoff, Tuples do not
support some of the object oriented idioms associated with inheritance. You
can get an overview in the section on [Tuples in the What's new in C# 7.0](whats-new/csharp-7.md#tuples) topic.
consistent rules for copies, equality tests, and assignments. As a tradeoff, Tuples do not
Copy link
Member

@jcouv jcouv May 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider fixing the casing on Tuples here as well and on the previous line.
Basically, tuples should be lowercased, except when referencing System.Tuple or System.ValueTuple types.

The language supports assignment between tuple types that have
the same number of elements and implicit conversions for the types for each of those
elements. Other
the same number of elements where each right-hand side element can be implicitly converted to its corresponding left-hand side element. Other
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the document seems to handle long lines in two different ways. Some are broken, and some are not. I don't know what the "correct way" is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've gone back and forth on that question. Many tools support line breaks only at paragraph boundaries, but reviews and responding are harder. So there is a mix. It's on our list to have a general guideline, but hasn't been decided yet.


You construct a tuple for the members that participate in value-based equality, then test the tuples for equality.

Deconstruction conversions are not applicable for testing equality. The following example does not compile:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the language perspective, deconstructions are carefully discussed as not being "conversions", because that would open questions of whether they should combine, or be inferred, etc.
Maybe "Deconstruction operators do not participate in testing equality"?

Console.WriteLine(p);
```

The deconstruct method could convert the person object `p` to a tuple containing two strings, but it is not applicable in the context of equality tests.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: The Deconstruct method...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, added a codefence.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Thanks

Copy link
Contributor

@rpetrusha rpetrusha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, @BillWagner. Left a number of comments and suggestions.


For any field where an explicit name is not provided, an applicable implicit
name will be projected. Note that there is no requirement to provide semantic names,
name will be projected. There is no requirement to provide semantic names,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: present tense is better than the 2 occurrences of the future tense here (also in line 129).


## Equality and tuples

Beginning with C# 7.3, tuple types support the `==` and `!=` operators. These operators work by comparing each member of the left argument to each member of the right argument in order. These comparisons short-circuit. The `==` operator stops evaluating members as soon as one pair are not equal. The `!=` operator stops evaluating members as soon as one pair is equal. The following code examples use `==`, but the conversion rules all apply to `!=`. The following code example shows an equality comparison for two pairs of integers:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • one pair are --> one pair is
  • "but the conversion rules all apply to != -- This isn't clear. If you mean comparison rules, this reads better as "but the comparison rules apply to != as well." If you mean conversion rules, it's probably best deleted.


[!code-csharp[TupleEquality](../../samples/snippets/csharp/tuples/tuples/program.cs#Equality "Testing tuples for equality")]

There are several rules that make tuple equality tests more convenient. Tuple equality performs lifting conversions if one of the tuples is a nullable tuple, as shown in the following code:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lifting conversions --> the spec refers to it as lifted conversions. I think I'd make "lifted conversions" a link: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/conversions#lifted-conversion-operators.


[!code-csharp[NullableTupleEquality](../../samples/snippets/csharp/tuples/tuples/program.cs#NullableEquality "Comparing Tuples and nullable tuples")]

Tuple equality also performs implicit conversions on each member of both tuples. These include lifted conversions, widening conversions, or other implicit conversions. The following examples also show that the conversions may create a temporary tuple for the left tuple, the right tuple, or both:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The temporary tuple is an implementation detail that I'm not sure I would mention (and the example doesn't really show it). I think that I'd just mention that the integer 2-tuple is equal to the long 2-tuple because of an implicit conversion of integer to long.

The names of the tuple members do not participate in tests for equality. However, if one of the operands is a tuple literal with explicit names, the compiler generates a warning if those names do not match the names of the other operand.
In the case where both operands are tuple literals, the warning is on the right operand as shown in the following example:

[!code-csharp[MemberNames](../../samples/snippets/csharp/tuples/tuples/program.cs#SnippetMemberNames "Tuple member names do not participate in equality tests")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you should mention the compiler warning number -- CS8383. And perhaps create a page for it in language-reference/compiler-messages/? (It would be best as a short-term fix to add it to misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md, but that seems to be for compiler errors and not warnings.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did add the warning number. I did write #5410 to update warnings we've haven't covered yet. (I'm sure there's more than the one.)

The language supports assignment between tuple types that have
the same number of elements and implicit conversions for the types for each of those
elements. Other
the same number of elements where each right-hand side element can be implicitly converted to its corresponding left-hand side element. Other
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comma between elements and where


This version enumerates the sequence exactly once. But, it's not very
reusable code. As you keep working, you'll find that many different
This version enumerates the sequence exactly once. But, it's not reusable code. As you keep working, you'll find that many different
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No comma after But

`Deconstruct` method for `Person` has two output parameters, and the `Deconstruct`
method for `Student` has three.

Tuple equality enables more concise code for your types. The following example adds equality tests, and related overrides for `Person` class:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no comma after tests
for Person class --> for the Person class
This seems like a digression, though; can you relate it more closely to tuple deconstruction?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It did feel like a digression.

I have two ideas.

The one I like best is to create a new tutorial on techniques for programming with tuples.

The alternative is that I could expand the explanations in these samples. That would tie it back in, but would make an already long article even longer.

What are your thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a new tutorial with techniques for programming with tuples could be really valuable, @BillWagner. That would be my preference.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue #5432 created.


You construct a tuple for the members that participate in value-based equality, then test the tuples for equality.

Deconstruction conversions are not applicable for testing equality. The following example does not compile:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps mention is generates CS0019

There are two conditions where candidate field names are not projected onto the tuple field:

1. When the candidate name is a reserved tuple name. Examples include `Item3`, `ToString` or `Rest`.
1. When the candidate name is a reserved tuple name. Examples include `Item3`, `ToString` or, `Rest`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The last comma should go before or.


## Equality and tuples

Beginning with C# 7.3, tuple types support the `==` and `!=` operators. These operators work by comparing each member of the left argument to each member of the right argument in order. These comparisons short-circuit. The `==` operator stops evaluating members as soon as one pair are not equal. The `!=` operator stops evaluating members as soon as one pair is equal. The following code examples use `==`, but the conversion rules all apply to `!=`. The following code example shows an equality comparison for two pairs of integers:
Copy link
Contributor

@pkulikov pkulikov May 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the beginning of the paragraph should we specify: ValueTuple type supports == and != operators? Maybe not, since the whole article is about those tuples.
Is it clear to the audience that tuple types don't include Tuple type?
However, after some thought, it seems it should be obvious that Tuple type is excluded by the introduction text. So, this comment might be ignored.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆 That was my analysis as well.

Console.WriteLine(p);
```

The deconstruct method could convert the person object `p` to a tuple containing two strings, but it is not applicable in the context of equality tests.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codefence Person type: ...could convert the Person object p to...?

@@ -1,19 +1,19 @@
---
title: Tuples - C# Guide
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Title should be updated to Tuple types

ms.date: 05/15/2018
ms.assetid: ee8bf7c3-aa3e-4c9e-a5c6-e05cc6138baa
---
# C# Tuple types #
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, one sweep should be made to lowercase Tuple where necessary. For example, here it should be C# tuple types

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Did not change any instance of "Tuple" that was
. in code
. in xref
. beginning of a sentence

---
# C# Tuple types #

C# Tuples are types that you define using a lightweight syntax. The advantages
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it start like C# tuple types are types... in order not to mix with the Tuple type?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's clear, now that the "Tuples" is not capitalized.

Great comments all.
Copy link
Contributor

@rpetrusha rpetrusha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks really good, @BillWagner. It's ready to merge.

This suggests a tutorial that shows several idiomatic tuple scenarios.
@BillWagner BillWagner merged commit c19c3ce into dotnet:master May 16, 2018
@BillWagner BillWagner deleted the csharp73-tuple-equality branch May 21, 2018 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants