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

Prototype: target typed "default" #13602

Closed
29 of 35 tasks
jcouv opened this issue Sep 4, 2016 · 28 comments
Closed
29 of 35 tasks

Prototype: target typed "default" #13602

jcouv opened this issue Sep 4, 2016 · 28 comments
Assignees
Labels
Area-Compilers Resolution-Fixed The bug has been fixed and/or the requested behavior has been implemented
Milestone

Comments

@jcouv
Copy link
Member

jcouv commented Sep 4, 2016

Work items:

  • Parsing
  • Target typing
  • Overload resolution
    • Report error if failed inference
    • Only non-nullable types should be considered as candidates
  • Verify semantic model (GetConstantValue, GetConversion, GetOperation)
  • IDE refactoring to simplify (when possible) or expand
  • Write spec (issue, proposal)
  • Validate IDE scenarios
  • Update prototype with latest LDM decisions
    • Use literal syntax node
    • Update as and is scenarios.

Test ideas:

  • dynamic x = default; // error
  • const int x = default; // ok
  • var x = default; // error
  • (int, int) t = (default, default); // ok
  • int[] t = new[] { default }; // ok
  • ITest i = default; // error
  • @default
  • default.ToString();
  • M(default); where void M<T>(T x) { ... } // error
  • flag ? default : 1;
  • default in enum?
  • more test on overload resolution: M(default, 1), M(default, (1, 2))
  • test const object x = default(S);
  • test C[] x = new[] { default };
  • test null == default

LDM questions:

  • Is "default" a literal?
  • Can you apply a cast on "default"? var x = (int)default; (I think the answer is yes).
  • Can "default" be used as default parameters? (current behavior is yes)
  • Can "default" appear in constant expressions? (current behavior is yes)
  • Can type-targeted default be applied anywhere the traditional "default" was used (including reference types)? (current answer is yes, including reference types)
  • throw default;? (current behavior is no)
  • default has a type (which is inferred) and also a constant value (if appropriate)
  • Should case default: give a warning (LDM 3/7)

Relates to language proposals #7737 and #13255

Overload resolution might re-use some techniques from #11493

@jcouv jcouv self-assigned this Sep 4, 2016
@AdamSpeight2008
Copy link
Contributor

AdamSpeight2008 commented Sep 4, 2016

What happens if default already exists in scope as parameterless method / property or a constant

Can "default" be used as default parameters?

Yes because it save the author having to write the type again.
eg SomethingClass<T0,T1,T2> thisparameter = default,

@jcouv
Copy link
Member Author

jcouv commented Sep 4, 2016

@AdamSpeight2008

What happens if default already exists in scope as parameterless method / property or a constant?

default is a reserved keyword, so methods, properties or constants couldn't use it as name (example).

@AdamSpeight2008
Copy link
Contributor

@jcouv @default is though.

@alrz
Copy link
Contributor

alrz commented Sep 4, 2016

ITest i = default; // error

Why? Shouldn't it be equivalent to default(ITest)?

@HaloFour
Copy link

HaloFour commented Sep 4, 2016

@AdamSpeight2008

The compiler requires that any reference of a keyword as an identifier be prefixed with @. But I can see where the following could be considered ambiguous:

int x = 2;
int @default = 3;
int result = x + default; // oops, sets result to 2
int correct = x + @default;

@svick
Copy link
Contributor

svick commented Sep 4, 2016

@HaloFour I don't see how is that different from the following, currently valid code:

int? x = null;
int @null = 0;
int? result = x ?? null; // oops, sets result to null
int? correct = x ?? @null;

@HaloFour
Copy link

HaloFour commented Sep 4, 2016

@svick

I agree. It's not a big enough of a concern to reconsider the feature. Anyone who explicitly decides to use keywords as identifiers via @ accepts the responsibility of ensuring that they don't mix them up.

@jcouv
Copy link
Member Author

jcouv commented Sep 4, 2016

ITest i = default; // error. Why?

@alrz There was no LDM discussion or decision on this, but my thinking is that default does not overlap with null (you can use one or the other, but not both). So default would be for structs and non-nullables only.
I agree with you this is not obvious, as you could see default as a simplification of default(ITest) and today C# does allow ITest i = default(ITest);. I'll add to the list of open questions.

@AdamSpeight2008
Copy link
Contributor

@HaloFour

int @default = 3;
int result = default; // oops, sets result to ??

Is that result 3 or 0.

@HaloFour
Copy link

HaloFour commented Sep 5, 2016

@AdamSpeight2008

Indeed, I already pointed that out. But as @svick noted that's already the case with null and @null and, frankly, the developer that takes it upon themselves to use keywords as identifiers accepts the responsibility of not mixing them up.

@AdamSpeight2008
Copy link
Contributor

AdamSpeight2008 commented Sep 5, 2016

It think the following syntax is more in keeping with C#.

F( int x?, string s?, int? n?, bool b? )

equivalent to

F( int    x = default(int),
   string s = default(string),
   int?   n = default(nullable<int>),
   bool   b = default(bool) )

@jcouv
Copy link
Member Author

jcouv commented Sep 5, 2016

@AdamSpeight2008

Is that result 3 or 0.

default is always a keyword. @default is always an identifier.
int result = default; // result is set to zero (regardless of any locals called @default declared in scope).

@CyrusNajmabadi
Copy link
Member

There was no LDM discussion or decision on this, but my thinking is that default does not overlap with null (you can use one or the other, but not both)

That seems unfortunate. It would be nice to have a single literal you could use for everything.

@CyrusNajmabadi
Copy link
Member

Is "default" a literal?

Out of curiosity, is there any reason why we wouldn't want to make 'default' as close to 'null' as possible, except that it would also be allowed for non-reference types?

@AdamSpeight2008
Copy link
Contributor

Make it behave similarly to VB's Nothing when it used in assignment.

@CyrusNajmabadi
Copy link
Member

@AdamSpeight2008 does that bring any interesting additional semantics you care about?

@HaloFour
Copy link

HaloFour commented Sep 6, 2016

@AdamSpeight2008

Make it behave similarly to VB's Nothing when it used in assignment.

To quote @AnthonyDGreen when responding to a complaint about Nothing equating to 0 in VB.NET:

One of my great regrets 🙁

In short, that's an absolutely awful idea.

@jcouv

In my opinion, default should be nothing more than shorthand for default(T) where T can be inferred by the compiler. No more. No less. That means that it should absolutely mean null where T is a reference type or interface. I believe that is going to be the expected behavior, anything else will be surprising in a bad way.

@AdamSpeight2008
Copy link
Contributor

AdamSpeight2008 commented Sep 6, 2016

Link to Docs
If the target type is a class, it assigns it of zero (null). if it target is a structure it assign it the zero value (0).
eg

string s = nothing; //  (s == null) == true  or the default value of the type.
Int i = nothing; // ( s == 0 ) = true or the default value of the type.

I think that comment is about the expression Nothing = 0. Akin to C's define NULL = 0;

( default == 0 ) == true would also be true in C#

There is a quirk in VB.net Nothing == "" evaluates to true.

@CyrusNajmabadi
Copy link
Member

Is there any difference between those semantics and the semantics of "default(T)" where T is whatever type is present?

@CyrusNajmabadi
Copy link
Member

In other words, i see 'default' as just being shorthand for "default(T)". Are there additional VB semantics you see on top of that.

@AdamSpeight2008
Copy link
Contributor

@CyrusNajmabadi That's how I also see it, shorthand for default( T ). It save the developer writing the type explicitly again. It like the dual of var

@HaloFour
Copy link

HaloFour commented Sep 6, 2016

@AdamSpeight2008

Ok, yes, I agree. I makes sense for default to behave like Nothing in VB.NET, which is like default(T) in C# today. What doesn't really make sense is the fact that Nothing in VB.NET behaves like that. 😄

@AdamSpeight2008
Copy link
Contributor

I hope that's because Erik Meijer had something to do with the implementation.

@CyrusNajmabadi
Copy link
Member

@AdamSpeight2008 Ah ok. I would not want it to be like VB's Nothing then. I would prefer it be like C#'s default(T).

@DavidArno
Copy link

I agree with others here who have questioned why ITest i = default; is viewed as an error. The LDM seem to have misunderstood/ignored the contents of the linked issues, which is that default would be the equivalent of default(T), for situations where T is known. So the following should apply:

dynamic x = default; // error, type isn't specified
var x = default; // error, type isn't specified
ITest i = default; // OK: default is shorthand for default(ITest)

@jcouv
Copy link
Member Author

jcouv commented Sep 6, 2016

@DavidArno There was no LDM discussion of this feature yet.
I got the feedback from you and others in the thread that there is strong interest to allow the default literal anywhere the default operator could. Thanks :-)

@gafter gafter added this to the 2.1 milestone Sep 7, 2016
@jcouv
Copy link
Member Author

jcouv commented Sep 20, 2016

Per your feedback, I have changed the prototype to allow default on reference types. I'll keep the LDM question open to confirm.

@jcouv
Copy link
Member Author

jcouv commented Apr 6, 2017

This is feature complete, as far as I can tell. No known work left. Completed a manual test pass in IDE.
Ready to merge back to master. I'll close this list now.

@jcouv jcouv closed this as completed Apr 6, 2017
@jcouv jcouv added the Resolution-Fixed The bug has been fixed and/or the requested behavior has been implemented label Apr 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Resolution-Fixed The bug has been fixed and/or the requested behavior has been implemented
Projects
None yet
Development

No branches or pull requests

8 participants