Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up[Discussion] Constant string interpolation #11259
Comments
ashmind
changed the title
[Discussion] String interpolation for constants
[Discussion] Constant string interpolation
May 11, 2016
This comment has been minimized.
This comment has been minimized.
Similar changes were proposed several times before (see e.g. #4678). They were closed, because of issues regarding specific behavior of |
This comment has been minimized.
This comment has been minimized.
@svick Yes -- it's clear that implicit approach cannot work here. However explicit approach can since it would explicitly limit what can be placed in So this limits supported scenarios to just strings and nulls I think, and culture or custom formatters will be ignored in the same way as |
This comment has been minimized.
This comment has been minimized.
A more formal proposal (a bit ad-hoc, not spec-language yet): If string interpolation expression is interpreted as a constant, it can be compiled to a constant string if: all values in An expression is interpreted as a constant if:
|
gafter
added
Discussion
Area-Language Design
labels
May 12, 2016
This comment has been minimized.
This comment has been minimized.
HaloFour
commented
May 12, 2016
I don't see how that remedies the issue mentioned by @gafter concerning custom formatting and culture. With this proposal it would be quite possible for the two following expressions to return different values: const string world = "World";
string greeting1 = $"Hello {world}!";
const string greeting2 = $"Hello {world}!"; |
This comment has been minimized.
This comment has been minimized.
context-based constness seem to be not a good option becasue the returned value might vary. I did suggest |
This comment has been minimized.
This comment has been minimized.
@HaloFour If I understand the problem correctly, the case is "culture that overrides format insertion for @alrz I've searched for similar discussions, but unfortunately missed that one. I think |
This comment has been minimized.
This comment has been minimized.
HaloFour
commented
May 13, 2016
@ashmind Correct. It's fully possible to write a PigLatin culture and set it to the default for the current thread which will rewrite arbitrary string values, e.g.: It may be an edge case, but it's still the prescribed behavior according to the specification and why all of the previous requests to either optimize interpolation into simple concat and/or to permit interpolation in constant expressions have not moved forward. |
This comment has been minimized.
This comment has been minimized.
@HaloFour Edge case you say, the thing is, string concatenation/interpolation should be considered as a low level feature and not something on top of internationalization and culture API which itself is a full-blown disappointment. |
This comment has been minimized.
This comment has been minimized.
Only in non-constant situation -- we don't have prescribed behavior in constant case yet. Yes, prescribing it not to use culture would be inconsistent -- but is it a problem enough to require explicit opt-in instead? I can't think of a single real-world case where someone could run into it (and if they do, they would have other problems with libs etc). |
This comment has been minimized.
This comment has been minimized.
bbarry
commented
May 13, 2016
Explicit opt-in could make it possible I suppose.
|
This comment has been minimized.
This comment has been minimized.
mklemarczyk
commented
Aug 8, 2016
•
String interpolation of a few string constants should be possible without making any changes. |
This comment has been minimized.
This comment has been minimized.
HaloFour
commented
Aug 8, 2016
Concatenation doesn't involve the current culture. Formatting does, and string interpolation is based on formatting. Using |
This comment has been minimized.
This comment has been minimized.
mklemarczyk
commented
Aug 8, 2016
•
So you can change your implementation in compiler to solve that bug. It can be String.Format for non-constants and simple string concatenation for constraints. It does not affect way how it work and does not have any performance issues. It would just solve that bug and make possible developers to use new syntax. |
This comment has been minimized.
This comment has been minimized.
HaloFour
commented
Aug 8, 2016
It's not a bug, it was explicitly designed to function like this. You not liking it doesn't make it a bug.
const string FOO = "FOO";
const string BAR = "BAR";
string foobar = $"{FOO}{BAR}";
const string FOOBAR = $"{FOO}{BAR}"; // illegal today
Debug.Assert(foobar == FOOBAR); // might not always be true |
This comment has been minimized.
This comment has been minimized.
I made a little proof of concept turning interoplation of string constants into just a string constant (rather than a call to string.Format): I could be overlooking something, but currently things like current culture does not effect how strings are treated when they are the arguments to string.Format call. So this sort of optimization should be harmless, unless in the furture string.Format starts to behave differently on the same input. That seems unlikly though. |
This comment has been minimized.
This comment has been minimized.
HaloFour
commented
Aug 9, 2016
Read the following: #6738 (comment) Even strings may be affected by the current culture depending on how it's implementation of |
This comment has been minimized.
This comment has been minimized.
@HaloFour A legitimate concern though would be this type of optimization might complicate the C# spec. Currently the spec just says the meaning of an interoplated string is "call string.Format". Changing the compiler to just emit a string might require specifying the behavior of string.Format, which would complicate the spec a little bit. |
This comment has been minimized.
This comment has been minimized.
eyalsk
commented
Oct 23, 2016
•
@ashmind Maybe it's possible to use backticks similarly to how it's used in JavaScript.
This will also be compatible with this:
|
Unknown6656
referenced this issue
Nov 8, 2016
Closed
[Umbrella] How would you imagine constexpr in C#? #15079
This comment has been minimized.
This comment has been minimized.
scalablecory
commented
Dec 11, 2018
I would like this if it were limited very specifically to e.g. nameof() and maybe invariant interpolation with compile-time constants. Here's one example where I could have used this:
|
IanKemp
referenced this issue
Dec 14, 2018
Closed
Proposal: Replace string.Format with concatenation when the string uses only nameof #31790
gafter
closed this
Dec 14, 2018
This comment has been minimized.
This comment has been minimized.
Issue moved to dotnet/csharplang #2077 via ZenHub |
ashmind commentedMay 11, 2016
Problems
There are two relevant cases, and both of them are related to
nameof()
.Consider the following code:
Even though
nameof
is a constant I have to fall back on older syntax here.Another (more insidious) example:
Even though approaches seem similar, the first one is a constant, while the second one does string allocation — defeating the purpose of a
StringBuilder
. This can be partially mitigated by having aFormattableString
overload onStringBuilder
, butFormattableString
itself and its internal array would still need allocations.Solution Discussion
I would like to evaluate string interpolation as a constant in certain contexts (that could only work if all values in it were constants). But I can't think of a simple syntax.
One option could be something like
(const)$"A {nameof(B)} C"
, but I'm not too fond of it.