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

Champion "Const Var" #106

Open
5 tasks
gafter opened this issue Feb 14, 2017 · 27 comments
Open
5 tasks

Champion "Const Var" #106

gafter opened this issue Feb 14, 2017 · 27 comments
Assignees
Milestone

Comments

@gafter
Copy link
Member

gafter commented Feb 14, 2017

  • Proposal added
  • Discussed in LDM
  • Decision in LDM
  • Finalized (done, rejected, inactive)
  • Spec'ed

See also dotnet/roslyn#4423

@gafter gafter changed the title Const Var Champion Const Var Feb 15, 2017
@gafter gafter changed the title Champion Const Var Champion "Const Var" Feb 21, 2017
@gafter gafter added this to the X.X candidate milestone Feb 22, 2017
@Pzixel
Copy link

Pzixel commented Mar 28, 2017

most of use cases of var are anonymous types or very long names like IGrouping<IEnumerable<IDictionary<...,....>, ...>> and so on. There is no problem with writing const int or const string especially when people frequently has rules like explicit declaration for primitive types. It's not a bad feature, but just useless, especially when you know that every feature starts with -100 points and you should outweight it with some benefit. I don't see any benefit here, until we can declare const of any type.

@CyrusNajmabadi
Copy link
Member

most of use cases of var are anonymous types or very long names like IGrouping<IEnumerable<IDictionary<...,....>, ...>> and so on

I don't believe there is any data that supports that statement. Teams (Roslyn-IDE for one) may just choose to use 'var' for all types where it can be used.

@jnm2
Copy link
Contributor

jnm2 commented Mar 28, 2017

I use var for all locals.

@Pzixel
Copy link

Pzixel commented Mar 28, 2017

@CyrusNajmabadi this feature is as simple as implement _ to be a separator in numbers, but it just doesn't provide any expressiveness.

@jnm2 it's quite common to explicitly specify simple types. R# even has a rule for it

image

I'm not saying it's completely useless, but here is bunch of much better champions.

@jnm2
Copy link
Contributor

jnm2 commented Mar 28, 2017

@Pzixel I'm aware of that, and I'm also aware that it's quite common not to specify simple types.

I bemoan the fact that var (signifying "variable") doesn't work well with const, just like it doesn't work well as a return type. But it's probably best to stick with var and redefine it mentally to mean "auto" rather than "variable." Just like "ReadOnly" now signifies "Readable" in .NET APIs. It's an artifact of history.

@weitzhandler
Copy link

var could be omitted.

@CyrusNajmabadi
Copy link
Member

Working on PR here: dotnet/roslyn#21149

@HekiShavik
Copy link

The var in const var a = "A"; is moot in my oppinion. I find the EcmaScript let a = "A"; and const a = "A"; syntax quite natural - even with the very limited amout I write - and while I rarely use const string a = "A"; in C#, I am completely on board with @weitzhandler and I wouldn't even think to use const var a = "A"; unless Roslyn or ReSharper were extremely adamant about it. Even then I'd feel the var is very redundant and unnecessary to the point where I would refrain from using the const keyword at all in that connection simply because I feel it muddies my code.

I get why this isn't getting much attention because I only see the real benefit with enums:

const TravellerBase.TravellerType typeFilter = TravellerBase.TravellerType.Adult | TravellerBase.TravellerType.Youth;

versus

const typeFilter = TravellerBase.TravellerType.Adult | TravellerBase.TravellerType.Youth;

By the way, if using gets to loose its brackets entirely, this would definitely be a piece of cake to implement and actually increase readability unlike the pattern based usings..

@gafter gafter removed their assignment Mar 13, 2020
@hrumhurum
Copy link

Currently we can do var s = "123" but we cannot do const s = "123".

Fields are in question, and generally speaking they should not be inferred for const as for now. Just to mirror the same choice made for var: vars are not allowed for fields.

const var syntax is out of question, as it represents a conflicting statement: the value cannot be a constant and a variable at the same time, it just does not make sense.

But local inferred const values are a way to go:

void Main()
{
    const s = "Hello const!";
    Console.WriteLine(s);
}

That would be a great addition to C#. Personally I hit this omission several times a week.

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Jun 2, 2020

const var syntax is out of question,

It's definitely not out of the question :). 'var' doesn't mean 'the value varies'. it means 'the type is inferred here'. So const var means 'a constant, whose type is inferred'.

var doesn't mean it varies anymore than int i means "i varies". var is in place of the type, and only means is inferred. That's why we don't say var i: int, just var i.

@Pzixel
Copy link

Pzixel commented Jun 2, 2020

Interesting fact: Rust has let statement with optional type ascription for anything but constants, where it's required.

@CleanCodeX
Copy link

CleanCodeX commented Sep 25, 2020

I find this apporach very useful. I don't care if it is const var or just const alone.

@hrumhurum
Copy link

const var needs further considerations.

An example:

int x = 10;
const var finalResult = x + 5;

Would this be a valid code? If not, what syntax would be used for immutable local variables if they ever appear in C#?

Would it be sealed var? Or let?

E.g.

int x = 10;
sealed var finalResult = x + 5;

vs

int x = 10;
let finalResult = x + 5;

If you are OK with sealed var long term then const var would be fine as well -- both constructions follow the same spirit.

Alternatively, if you prefer to choose a concise let keyword for immutable local variables then it should be just const for type-inferred constants to preserve the common language spirit.

Both approaches work. Here are some syntax samples for your convenience:

// ------------------------------------------
// 1. const var / sealed var approach
// ------------------------------------------
const var s = "Hello";
int x = 10;
sealed int y = x + 1; // type is specified
sealed var z = x + 2; // type is inferred

// ----------------------------------------
// 2. const / let approach
// ----------------------------------------
const s = "Hello";
int x = 10;
let int y = x + 1; // type is specified
let z = x + 2; // type is inferred

My personal vote goes for const / let approach, but const var / sealed var is not bad at all, despite being chatty and a bit confusing in "const var" statement from a human linguistics standpoint (just like a "black white" color).

@CleanCodeX
Copy link

CleanCodeX commented Oct 1, 2020

My favorite ist just const with ommitting its type. const acts as var in that way.
const var seems to me to long for something const without type can do as well. I would not like to see sealed / let to introduce new meanings or occurrences of these words.

@HaloFour
Copy link
Contributor

HaloFour commented Oct 1, 2020

@hrumhurum

See #188

const means something very different to the C# compiler. const locals don't exist in IL, and const fields aren't proper fields that can be referenced and read either. The value must be evaluated at compile-time and embedded directly in any call or expression that uses it.

@weitzhandler
Copy link

weitzhandler commented Oct 1, 2020

My personal preference would be omitting the var. If you don't specifiy a type, you mean you want an inferred const type, though var can be allowed for those who like to see it.

And please don't introduce any new unrelated keywords like let, sealed or anything but readonly and const (both), where readonly is per scope and const is persistent/static.

@CleanCodeX
Copy link

@hrumhurum

See #188

const means something very different to the C# compiler. const locals don't exist in IL, and const fields aren't proper fields that can be referenced and read either. The value must be evaluated at compile-time and embedded directly in any call or expression that uses it.

How the runtime treats the "const [type]" expression and how it should "apear" to the developer in code is not necessarily the same. const without type could under the hood be compiled as const [type] as well.

@HaloFour
Copy link
Contributor

HaloFour commented Oct 1, 2020

@CleanCodeX

C# already treats them differently, readonly vs const. The latter has a lot of restrictions since it must be evaluated by the compiler and it must be something that can be embedded in assembly metadata. const expressions will never be evaluated at runtime, readonly expressions always will.

@CleanCodeX
Copy link

@CleanCodeX

C# already treats them differently, readonly vs const. The latter has a lot of restrictions since it must be evaluated by the compiler and it must be something that can be embedded in assembly metadata. const expressions will never be evaluated at runtime, readonly expressions always will.

I know. If const without type is limited to constant expressions, there is no reason not to ommit the type argument. the compiler can choose at design time which type it is. the things only get more difficult when the const value needs to be evaluated first.

@CleanCodeX
Copy link

CleanCodeX commented Oct 1, 2020

I see no reason why:

const a = 3;
const b = "a";

cannot be compiled as
const int a = 3;
const string b = "a";

if some wants a different type than the compiler chose, just type it. same applies for var, as well.

@weitzhandler
Copy link

if some wants a different type than the compiler chose, just type it. same applies for var, as well.

Or if someone wants to 'declare' they're type-inferring they could choose to type out const var = 3, although that doesn't have to be mandatory.

@HaloFour
Copy link
Contributor

HaloFour commented Oct 1, 2020

@CleanCodeX

I wasn't commenting on that specific syntax decision, only that const doesn't mean "immutable" and shouldn't be conflated with the other proposal to add such locals to the language.

@CleanCodeX
Copy link

I wasn't commenting on that specific syntax decision, only that const doesn't mean "immutable" and shouldn't be conflated with the other proposal to add such locals to the language.

I aggree. Const for constant expressions, readonly for the others seems to address the mentioned dfficulties.

@333fred 333fred modified the milestones: X.X candidate, X.0 candidate Oct 14, 2020
@hrumhurum
Copy link

Maybe 2023 will be finally the year of a const type inference in C#?

Writing long enums is especially annoying:

const DiscoveryOptions discoveryOptions = DiscoveryOptions.NoSort | DiscoveryOptions.Invariant;

instead of a more natural and concise statement below:

const discoveryOptions = DiscoveryOptions.NoSort | DiscoveryOptions.Invariant;

As it already had been mentioned, JavaScript has this feature since ES6 (2015) and it causes exactly zero problems. Why C# is still lagging on this front?

@theunrepentantgeek
Copy link

theunrepentantgeek commented Oct 7, 2023

JavaScript has this feature since ES6 (2015)

The keyword const has a very (very!) different meaning in JavaScript than it does in C#, plus the type systems are vastly different.

Why C# is still lagging on this front?

Every feature has costs and benefits - including the opportunity cost that working on one feature means a different feature doesn't get progressed. C# doesn't have this feature because there are other, more valuable features, that have been prioritised.

That said, even in a mythical world of infinite resources, not every feature would make it into the language. The teams discipline in adding only the features that makes sense is to be applauded.

It's worth noting that this features has a champion, putting it ahead of many other features as someone on the C# team has decided this is valuable enough to progress further. Even that's no guarantee of progress though.

@glen-84
Copy link

glen-84 commented Jul 16, 2024

I have analyzers suggesting changing:

var key = "Foo";

To:

const string key = "Foo";

... but it's just so verbose.

I also think that, although var doesn't mean that the value varies, const var is still a bit awkward to read, and could be shorter.

const key = "Foo";

Are there any technical complications/ambiguities with this? Is this issue only blocked by available time and priorities?

@glen-84
Copy link

glen-84 commented Jul 22, 2024

@colejohnson66 @Zodt What do you disagree with?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests