Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuples #1

Merged
merged 6 commits into from
Jan 27, 2020
Merged

Tuples #1

merged 6 commits into from
Jan 27, 2020

Conversation

RexJaeschke
Copy link

Rex's first attempt to convert this proposal to standardize.

@BillWagner BillWagner self-requested a review January 22, 2020 20:52
Copy link
Owner

@BillWagner BillWagner left a comment

Choose a reason for hiding this comment

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

This is great work so far @RexJaeschke

I'll start an email thread with Mads, Julien and Neal to figure out where we file issues for this work. Then, I'll create issues and we can merge this and keep moving forward.

Note that because it is not a constant expression, a tuple literal cannot be used as default value for an optional parameter.
A tuple literal is *target typed* whenever possible; that is, its type is determined by the context in which it is used.

**ISSUE:** If the term target-typed is specific to this context, we probably need a complete definition somewhere.
Copy link
Owner

Choose a reason for hiding this comment

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

We used the term "implicitly typed", and defined it for the same concept in statements, where we specify implicitly typed local variables (var declarations).

there is some discussion that dances around the concept in integral and floating-point literals, but I did not see a definition.

Copy link
Author

Choose a reason for hiding this comment

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

I beefed up the text to say,

A tuple literal is implicitly typed; that is, its type is determined by the context in which it is used, referred to as the target. Each element expression in a tuple literal shall have a value that can be converted implicitly to its corresponding target element type.

and added the following examples showing acceptable and unacceptable implicit conversions:

(int, double) t3 = (0, 2);    // infer tuple type (int, double) from values; can implicitly convert int to double
(int, double) t4 = (0.0, 2);  // Error: can't implicitly convert double to int


In cases where a tuple literal is not part of a conversion, it acquires its *natural type*, which means a tuple type where the element types are the types of the constituent expressions, in lexical order. Since not all expressions have types, not all tuple literals have a natural type either:

**ISSUE:** Is natural type specific to tuples? Need we say more about this term?
Copy link
Owner

Choose a reason for hiding this comment

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

Yes, we should define this term.

Copy link
Author

Choose a reason for hiding this comment

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

I put the following definition in Tuple types|General:

A tuple's natural type is the combination of its element types, in lexical order, and element names, if they exist.

and then made uses link there.

Once we decide on what to do about "arity", we could rewrite the above definition in terms of that.

Copy link
Owner

Choose a reason for hiding this comment

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

Good plan.

return (s, c); // target typed to (int sum, int count)
}
```
As shown, a tuple can be initialized using a [tuple literal](../../spec/lexical-structure.md#Tuple-literals).
Copy link
Owner

Choose a reason for hiding this comment

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

The referenced section for the link doesn't exist yet. Should we refer to the addition described in this document for now?

Copy link
Author

Choose a reason for hiding this comment

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

I changed the link to "XXX", which I'm using as a placeholder for future links.


Because of the dual nature of tuples, it is not allowed to assign field names that overlap with preexisting member names of the underlying type. The only exception is the use of predefined `Item1`, `Item2`,...`ItemN` at corresponding position N, since that would not be ambiguous.
**ISSUE:** Where will the type System.Value be defined (and its public names listed)?
Copy link
Owner

Choose a reason for hiding this comment

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

I think this should be in the annex where we specify the necessary standard library.

Copy link
Author

Choose a reason for hiding this comment

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

I see that unlike the published standard, the GitHub-based spec does not have this annex. In any event, I added a new section to the proposal with definitions for this family of types for when such an annex is created.

I see that V7.3 will support ==/!= on tuples, and right now, System.ValueTuple.Equals exists. As such, I added a definition for tuple equality, and I posed added issue re relational semantics based on System.ValueTuple.CompareTo's behavior.

Copy link
Owner

Choose a reason for hiding this comment

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

Right on both counts.


When tuple elements names are used in overridden signatures, or implementations of interface methods, tuple element names in parameter and return types must be preserved. It is an error for the same generic interface to be inherited or implemented twice with identity convertible type arguments that have conflicting tuple element names
**ISSUE:** Re the mention of "tuple length", which is not mentioned elsewhere; it seems to me that a tuple type includes an implied length based on the number of elements.
Copy link
Owner

Choose a reason for hiding this comment

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

That's how I interpret it. This is the same as the arity term. We should standardize on arity, and define it.

Copy link
Author

Choose a reason for hiding this comment

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

Done!

> note:
>
> An element name at one position on one side of a conversion, and the same name at another position on the other side almost certainly have bug in the code:
In teh case in which an element name at one position on one side of a conversion, and the same name at a different position on the other side, the copmpiler shall issue a warning.
Copy link
Owner

Choose a reason for hiding this comment

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

nit:

Suggested change
In teh case in which an element name at one position on one side of a conversion, and the same name at a different position on the other side, the copmpiler shall issue a warning.
In the case in which an element name at one position on one side of a conversion, and the same name at a different position on the other side, the compiler shall issue a warning.

Copy link
Author

Choose a reason for hiding this comment

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

Got it; that's probably my most common typing mistake!

Copy link
Owner

Choose a reason for hiding this comment

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

me too.


Tuple conversions are *Standard Conversions* and therefore can stack with user-defined operators to form user-defined conversions.

**ISSUE:** Is 'stack' a defined term in this context?
Copy link
Owner

Choose a reason for hiding this comment

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

I don't think we've defined it. I'd prefer using different language in the previous sentence to introducing new terms. What are your thoughts?

Copy link
Author

Choose a reason for hiding this comment

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

How about replacing "stack" with "combine" or "be combined"?

Copy link
Owner

Choose a reason for hiding this comment

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

I think "be combined" would be best.

An implicit tuple conversion is a standard conversion. It applies between two tuple types of equal arity when there is any implicit conversion between each corresponding pair of types.

**ISSUE:** Re 'arity' does this mean number of elements, with their types and names? In any event, perhaps we should define this in terms of tuples and consistently use it throughout, as in, "The arity of a tuple is ...".
Copy link
Owner

Choose a reason for hiding this comment

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

arity means number of elements and their types. I don't think it includes names. We should verify that by looking at all uses.

Copy link
Author

Choose a reason for hiding this comment

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

I defined "arity" in Tuple types|General, as follows:

A tuple's arity is the combination of its element types, in lexical order; element names are not included.

and I reviewed the proposal, consistently using this term, as appropriate.

Having said that, my experience with using "tuple" has to do with counts only: the number of operands an operator takes or the number of arguments a function expects; type info does not enter into it. Yet, in the case of tuples, element type is significant. As such, like functions/methods, tuples really have "signatures", which capture both number and ordered type. Might we be able to use that term instead?

Overload resolution for `Deconstruct` methods considers only the arity of the `Deconstruct` method. If multiple `Deconstruct` methods of the same arity are accessible, the expression is ambiguous and a binding time error occurs.
**ISSUE:** I think we need to say more about this code (which is not an example, but is intended to show/say just what is going on/needed).

Overload resolution for `Deconstruct` methods considers only the arity of the `Deconstruct` method. If multiple `Deconstruct` methods of the same arity are accessible, the expression is ambiguous and a binding-time error shall occur.
Copy link
Owner

Choose a reason for hiding this comment

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

Regarding the "arity" definition. This paragraph implies that names aren't part of "arity".

Copy link
Author

Choose a reason for hiding this comment

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

Agreed!

**ISSUE:** Explain what the comment "Sure" means.
Copy link
Owner

Choose a reason for hiding this comment

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

This should be saying that the extension method M is a candidate method, even though the tuple t has different element names (a, b) than then formal parameter of M (x, y).

Copy link
Author

Choose a reason for hiding this comment

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

OK; I added that explanation to the end of the Note.

@BillWagner BillWagner merged commit 9f7b835 into BillWagner:add-tuple-proposal Jan 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants