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 "Constant interpolated strings" #2951

Open
4 of 5 tasks
agocke opened this issue Nov 12, 2019 · 51 comments
Open
4 of 5 tasks

Champion "Constant interpolated strings" #2951

agocke opened this issue Nov 12, 2019 · 51 comments
Assignees
Labels
Implemented Needs ECMA Spec This feature has been implemented in C#, but still needs to be merged into the ECMA specification Proposal champion Soon candidate
Milestone

Comments

@agocke
Copy link
Member

agocke commented Nov 12, 2019

Example:

const string s1 = $"abc";
const string s2 = $"{s1}edf";
@agocke agocke created this issue from a note in Language Version Planning (Any Time) Nov 12, 2019
@Joe4evr
Copy link
Contributor

Joe4evr commented Nov 12, 2019

@svick
Copy link
Contributor

svick commented Nov 12, 2019

As I understand it, the biggest problem with this feature is that the value of an interpolated string can depend on the current culture. How do you propose to solve that? In other words, if I had const string pi = $"{3.14}";, what would be the value of pi?

@YairHalberstadt
Copy link
Contributor

@svick
Ignore that and interpret it as "" + 3.14?

@HaloFour
Copy link
Contributor

From the notes:

A more useful version would allow constant interpolated strings if all of the substitutions are constant strings.

@ronnygunawan
Copy link

@YairHalberstadt Tried it on C# interactive:

> "" + 3.14
"3.14"
> System.Threading.Thread.CurrentThread.CurrentCulture =
. System.Globalization.CultureInfo.GetCultureInfo("id-ID");
. "" + 3.14
"3,14"

@333fred
Copy link
Member

333fred commented Nov 12, 2019

As I understand it, the biggest problem with this feature is that the value of an interpolated string can depend on the current culture. How do you propose to solve that? In other words, if I had const string pi = $"{3.14}";, what would be the value of pi?

@svick, we haven't come up with a full proposal yet, but in LDM yesterday we were of the opinion that you can't do that. You can only do things in const interpolated strings that are themselves const. "" + 3.14 is not a constant expression, so you can't interpolate it.

@MgSam
Copy link

MgSam commented Nov 12, 2019

What are the use cases of this feature?

This feature seems of such minor use that I have no idea how it made it to an LDM.

@CyrusNajmabadi
Copy link
Member

What are the use cases of this feature?

Building a constant string out of other constant, but allowing the user to use interpolations, instead of forcing them to use concatenation.

@HaloFour
Copy link
Contributor

It's a very slight difference, and the end result is the same.

I was going to mention reusable URI components in routing attributes as a use case, but then I remembered that those attributes use curly braces to denote path parameters, and that could end up being really confusing. That might be an argument against this feature.

@CyrusNajmabadi
Copy link
Member

IDE colorization should help with that @HaloFour. Right?

@HaloFour
Copy link
Contributor

@CyrusNajmabadi

IDE colorization should help with that @HaloFour. Right?

Unless you also have an IDE extension to colorize URIs in ASP.NET routing attributes? 😄

@MgSam
Copy link

MgSam commented Nov 13, 2019

What are the use cases of this feature?

Building a constant string out of other constant, but allowing the user to use interpolations, instead of forcing them to use concatenation.

That's saying how it works, not what the use cases are.

I can probably count on one hand how many times I could've used a feature like this in the 10+ years I've been writing C#. I don't understand how such a minor feature that no one is asking for makes it to an LDM but related (and much more useful requests), like expanding the set of compile-time allowed expressions don't.

What about using System.Math at compile time? What about reflection at compile time? All things people ask for ad-nauseam and that solve real problems. Why should string interpolation, which is just a fancy syntax sugar for stuff we can already do with concatenation at compile time, be the blessed operation that gets promoted?

I'm not saying that any of those other things should be prioritized or not prioritized at this time either, it just continues to strike me how completely arbitrary the LDM prioritization continues to be.

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Nov 13, 2019

That's saying how it works, not what the use cases are.

The use case is when i want to make a constant string and build it out of other constant strings. Formattable strings looks nicer and easier to read, so i would like to use those.

I don't understand

The LDM decides what they want to champion. It's that simple. :)

What about using System.Math at compile time?

What about it?

What about reflection at compile time?

What about it?

All things people ask for ad-nauseam and that solve real problems.

Ok. Convince an LDM member to take that up. It's not relevant in this proposal. :)

Why should string interpolation, which is just a fancy syntax sugar for stuff we can already do with concatenation at compile time, be the blessed operation that gets promoted?

Because an LDM member championed it.

it just continues to strike me how completely arbitrary the LDM prioritization continues to be.

It is arbitrary. The LDM prioritizes what they think is most relevant. Sometimes that means that little features get picked because an LDM member thinks it is worth it (and possibly because they're willing to find the time to make it happen).

@drewnoakes
Copy link
Member

I suspect I would use this most in DebuggerDisplay attributes:

// before
[DebuggerDisplay("{Foo}")]

// or maybe
[DebuggerDisplay("{" + nameof(Foo) + "}")]

// after
[DebuggerDisplay($"{{{nameof(Foo)}}}")]

@drewnoakes
Copy link
Member

Another use case:

[Obsolete($"Use {nameof(ILaunchSettingsProvider2)} instead.")]

@agocke
Copy link
Member Author

agocke commented Nov 19, 2019

Yeah, attribute arguments were the place I thought this most useful, and have run into it before. I championed it because I happen to know that we implemented an optimization that basically turns an interpolated string into a string.Concat call not too long ago, so I bet this would be pretty easy to implement.

@yaakov-h
Copy link
Member

@agocke the latest compiler doesn't just turn it into string.Concat. If all pieces are constants, it actually emits the concatenated/interpolated string as a single string:

https://sharplab.io/#v2:D4AQzABCBMEJIBkCGBXAdgYwBYGUCmALgQJZoDmAzgAoBOA9gG7EAmeNsA3gLABQE/EXgKgBGAGwQaeJMzpoANgE9RABggBZPBQpIyeCAF4IAEgBEAVQr6OaJAFs8dAGYAKRKky5CJctXpNWdgBKAF8IUgoCaWYAOlMAbl4QoA==

@agocke
Copy link
Member Author

agocke commented Nov 19, 2019

Yup, that's why I thought this would be pretty simple. Probably some stuff to mop up around constant folding, but overall shouldn't be too bad.

@gafter
Copy link
Member

gafter commented Nov 22, 2019

FYI: "" + 3.14 is not a constant in C#.

@uygary
Copy link

uygary commented Nov 27, 2019

@svick has a very fair and extremely important point. Culture dependency and unavoidable side effects that will be introduced by that is making me very wary about this.
Even though I love the uses cases, I'm not sure if this is a good idea.

@HaloFour
Copy link
Contributor

@uygary

This feature won't work in this scenarios. It'll only work for interpolating other constant strings, so locale is not a concern. It's really just a slightly different syntax for string concatenation.

@uygary
Copy link

uygary commented Nov 27, 2019

@HaloFour in that case I retract my objection. Thanks for clearing that up, and sorry for missing that quote from the notes.

@MadsTorgersen MadsTorgersen added this to the Any Time milestone Mar 28, 2020
@agocke agocke self-assigned this Mar 28, 2020
@jaredpar jaredpar self-assigned this Jun 8, 2020
@AustinWise
Copy link

Just for reference, this is a long-standing request. dotnet/roslyn#4678 was migrated from an internal Microsoft bug database in 2015. There are also a few issues in this repo related to this feature:

I look forward to this simple and straightforward improvement to the ergonomics of string interpolation in C#.

@aka-nse
Copy link

aka-nse commented Aug 3, 2020

Can #3044 give benefits this proposal?
When InvariantCulture is specified, not only const string but also const float seems to be available as an element of constant interpolation string.

@333fred 333fred added the Implemented Needs ECMA Spec This feature has been implemented in C#, but still needs to be merged into the ECMA specification label Dec 1, 2020
@CleanCodeX
Copy link

when is 16.9. about to be rolled out?

@333fred
Copy link
Member

333fred commented Dec 1, 2020

when is 16.9. about to be rolled out?

There's no public date I can share currently.

@jaredpar
Copy link
Member

jaredpar commented Dec 1, 2020

The best place to look for VS release dates, RTM and preview, is here

https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes

@CleanCodeX
Copy link

of course, this page I am checking daily. Is there any site where release dates are listed in advance? It's nasty that I daily have to check if there is a new version for VS installer to update. Is there any possibility to get notified via email if a new version is available? This is annoying.

@333fred
Copy link
Member

333fred commented Dec 1, 2020

It's nasty that I daily have to check if there is a new version for VS installer to update.

VS itself does update checks, and should let you know with a popup inside VS if there is a new version available.

@CleanCodeX
Copy link

CleanCodeX commented Dec 1, 2020

VS itself does update checks, and should let you know with a popup inside VS if there is a new version available.

well, sometimes this actually happens... in more than 90% of all new versions the new version was downloaded by myself before VS had any clue of it. not sure what the notification policy behind this is.

@theunrepentantgeek
Copy link

Based on my own observations, I believe VS checks daily.

@ViIvanov
Copy link
Contributor

Is it possible to allow alignment component in interpolation expression?

const string TitleHeader = "Title";
const string CountHeader = "Count";
const string TableHeader = $"{TitleHeader,-50}|{CountHeader, 10}";

@333fred
Copy link
Member

333fred commented Jan 28, 2021

No, at least not as proposed and implemented.

@ViIvanov
Copy link
Contributor

I think (maybe I'm wrong?) alignment can be implemented for const strings. Should I create a proposal for it?

@333fred
Copy link
Member

333fred commented Jan 28, 2021

I think (maybe I'm wrong?) alignment can be implemented for const strings. Should I create a proposal for it?

You are free to do so. However, we explicitly rejected alignment from the feature in order to keep it simple and avoid any dependence on the implementation of string.Format or potential culture dependence.

@ViIvanov
Copy link
Contributor

Thank you for the answer,

…keep it simple and avoid any dependence on the implementation of string.Format or potential culture dependence

is enough for me for understanding.

@IanKemp
Copy link

IanKemp commented Sep 7, 2021

What happened to this feature? https://github.com/dotnet/roslyn/blob/main/docs/Language%20Feature%20Status.md#c-100 states it was merged into 16.9 yet VS 2019 is currently on 16.11 with const interpolated strings nowhere to be seen - is this coming to VS 2019 ever? Or will it (and C# 10 as a whole) be restricted to VS 2022?

@jnm2
Copy link
Contributor

jnm2 commented Sep 7, 2021

@IanKemp This feature is working for me in 16.11.2 at the moment. Remember, you have to specify <LangVersion>preview</LangVersion> until November when C# 10 is released.

@IanKemp
Copy link

IanKemp commented Sep 7, 2021

@IanKemp This feature is working for me in 16.11.2 at the moment. Remember, you have to specify <LangVersion>preview</LangVersion> until November when C# 10 is released.

Thanks for the reminder, for some reason I had it in my head that langver=latest would do it. I also don't see any mention of this feature in the release notes for 16.9.x/16.10.x/16.11.x, which honestly doesn't surprise me because this whole C# language version vs IDE version vs .NET Runtime version matrix is getting rather horribly complicated. I'm hoping you guys are going to perform something of a reset in this regard when you do the big bang drop of C# 10 + .NET 6 + VS 2022 in November.

I mean, just looking at https://github.com/dotnet/roslyn/blob/main/docs/Language%20Feature%20Status.md#c-100 gives me anxiety.

@CyrusNajmabadi
Copy link
Member

When c#10 drops, 'latest' will work. Until then, you need 'preview'. This seems same and sensible.

is getting rather horribly complicated

I disagree, and I'm an ideal world these can be decoupled.

@jerviscui
Copy link

Will it solve the interpolated string boxing problem?

eg:

int a = 1;
return $"string {a}";

@ufcpp
Copy link

ufcpp commented Sep 8, 2021

@jerviscui
see https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/improved-interpolated-strings.md

FYI, interpolation with non-string could not be constant because of formatter dependency.

Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-us");
Console.WriteLine($"{1.2}"); // 1.2

Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("fr-fr");
Console.WriteLine($"{1.2}"); // 1,2

@jerviscui
Copy link

@ufcpp Thank you!
It's means must still use ToString() method, to avoid boxing a.

int a = 1;
return $"string {a.ToString()}";

@drewnoakes
Copy link
Member

Does the formatting of integers change across cultures?

@333fred
Copy link
Member

333fred commented Oct 22, 2021

Integers are not allowed in constant interpolated strings for that reason.

@jrmoreno1
Copy link

I was surprised to discover that $”{enum.T}” wasn’t considered constant…although of course $”{nameof(enum.T)}” is

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Implemented Needs ECMA Spec This feature has been implemented in C#, but still needs to be merged into the ECMA specification Proposal champion Soon candidate
Projects
None yet
Development

No branches or pull requests