Git Product home page Git Product logo

Comments (26)

iam3yal avatar iam3yal commented on July 17, 2024 19

@whut

I'd go with something like this:

$i"count: {count}"
$c"count: {count}"

The reason is the string can be lengthy and it might be annoying to look for, some people might miss it so for readability I'd go with a prefix and not postfix. :)

from csharplang.

dlemstra avatar dlemstra commented on July 17, 2024 10

How about using this syntax instead:

$("count: {count}", CultureInfo.InvariantCulture)

Where the second "argument" is an IFormatProvider.

from csharplang.

dlemstra avatar dlemstra commented on July 17, 2024 3

With this syntax you would not need to add the "static using" in every file. And you can easily put it in one of the other IFormatProviders. It's not smaller but I don't think the goal of interpolated strings is to make it smaller. It was added so you can just put your arguments at the place where you use it instead of worrying about the order of your arguments when you do a string.Format. And with my syntax you can easily add the CultureInfo when you need it.

from csharplang.

333fred avatar 333fred commented on July 17, 2024 3

This was addressed in C# 10 with interpolated string handlers: string.Create(CultureInfo.InvariantCulture, $"{somevalue} is formatted with invariant culture") will do this.

from csharplang.

M0ns1gn0r avatar M0ns1gn0r commented on July 17, 2024 2

This was addressed in C# 10 with interpolated string handlers: string.Create(CultureInfo.InvariantCulture, $"{somevalue} is formatted with invariant culture") will do this.

Meh, this doesn't address much as we already have a shorter version FormattableString.Invariant($"count: {count}").

from csharplang.

Athari avatar Athari commented on July 17, 2024 1

The problem with i suffix is that it may conflict with complex numbers, if a later version of C# will include literals for them like 5+2i...

However, I completely agree that the amount of code to use invariant culture is a bit too big. In case of interpolated strings, "using static" (using static System.FormattableString + Invariant("{foo}")) helps somewhat, but there're lots of other cases where it's much more complex. There's nothing in the framework to simplify string.Compare(s1, s2, true, CultureInfo.InvariantCulture) and numerous other methods, and suffixes for just string interpolation won't help much. 😞

from csharplang.

DmitryMak avatar DmitryMak commented on July 17, 2024 1

A related issue is that CA1305: Specify IFormatProvider warning does not apply to interpolated strings (as described here). IMHO having no short symmetrical syntax for Current and Invariant cultures makes Globalization warnings ineffective. Should there be no Globalization warnings or should they require a verbose explicit syntax?

string.Create(CultureInfo.InvariantCulture, $"{somevalue})
string.Create(CultureInfo.CurrentCulture, $"{somevalue})

The warning wouldn't even be required if there was a short symmetrical syntax

#"{somevalue} // invariant culture
$"{somevalue} // current culture

from csharplang.

KrisVandermotten avatar KrisVandermotten commented on July 17, 2024

See also dotnet/roslyn#12298

from csharplang.

vladd avatar vladd commented on July 17, 2024

Just for interpolated strings, I'd propose an alternate prefix. Perhaps $$ instead of $.

(This however doesn't solve the problem of having to specify InvariantCulture in many other places, so if someone finds a more general solution, it should be preferred.)

from csharplang.

whut avatar whut commented on July 17, 2024

@Athari

Complex numbers are digits only (and + and i), so there will be no conflict with strings that are marked with double quotes.

@Athari @vladd

Other cases you mention are just method calls, it's out of the scope of this topic, that is the extension to interpolated strings syntax.

from csharplang.

jods4 avatar jods4 commented on July 17, 2024

String interpolation is so convenient I see people use it everywhere, even for $"x = {x}" kind of code. So yay for the C# feature but most dev don't realize:

  • The current culture is used, so the many usages to format HTML, SQL, XML, JSON, URL, culture-neutral logs and co. are often dubious;
  • Interpolation is a lot more heavy than doing "x = " + x. It is boxing, allocating and always formatting (even for strings).

With the right using you can indeed do Invariant($"x = {x}") which in my opinion helps already a lot. But very few people seem to even know that an interpolation can be IFormattable, or the existence of the Invariant() helper.

  • It is hard to discover / little known by the dev community.
  • It is still verbose if you write mainly code that produces machine-strings (as opposed to user-facing).
  • It doesn't improve perf.

Although I don't like the suffix proposal, I would love to see a shorthand for Invariant($"x = {x}"). Because:

  • More people would learn about the new language feature (and use it).
  • It will be much shorter / nicer.
  • C# could produce optimal code that creates the string without boxing, allocating or formatting when it's not necessary.

As for the syntax, I think it's better if we keep everything at the same place, i.e. at the start. Maybe $i"x"? It becomes a bit hieroglyphic with verbatim, though: $i@"x...". Or alternative symbol %"x"?

EDIT: I think the $$"x" proposal is not so bad. If there's no better suggestion I'd 👍

from csharplang.

Athari avatar Athari commented on July 17, 2024

@dlemstra How is it better than the current Invariant($"count: {count}")?

from csharplang.

Opiumtm avatar Opiumtm commented on July 17, 2024

It's counter-intuitive. Indeed it looks like error in source file.

$"count: {count}"c    // this will call string.Format with CultureInfo.CurrentCulture
$"count: {count}"i    // this will call string.Format with CultureInfo.InvariantCulture
$"count: {count}"     // as it is now, this will call string.Format without CultureInfo, effectively (...)

This approach is much better and understandable from the first sight:

$("count: {count}", CultureInfo.InvariantCulture)

from csharplang.

whut avatar whut commented on July 17, 2024

@Opiumtm adding dollar sign before the double-quote for interpolated string is also counter-intuitive if you look from the perspective of C# 5 :)

from csharplang.

whut avatar whut commented on July 17, 2024

@eyalsk 👍

from csharplang.

nanoant avatar nanoant commented on July 17, 2024

@dlemstra How is it better than the current Invariant($"count: {count}")?

Different in two aspects. First, FormattableString.Invariant needs underlying FormattableString instance, hence we need to allocate FormattableString on heap and this is won't fix see dotnet/roslyn#15395 - closed by @gafter.

This could be avoided if FormattableString was a struct proposed in dotnet/roslyn#518 - dismissed by @gafter after providing good argumentation.

Nevertheless, with the proposed new syntax, if $"..." is just a syntactic sugar for string.Format(...) then I would expect $$"..." or $("...", CultureInfo.InvariantCulture) to be just a sugar for string.Format(CultureInfo.InvariantCulture, ...) (or actually any culture), hence no need for intermediate FormattableString instance.

Second, the necessity of putting using static System.FormattableString and Invariant( in the front of your text if you intend to use string interpolation for logging or exception messages really reduces readability of the code without a good reason.

Altogether, this may look like a discussion about some petty syntax addition, but I believe we have inherent problem with interpolated strings that not that petty.

@gafter I would really appreciate if you could take a stance here, since you were involved the other issues related to string interpolation that are now closed, but no improvement was made so far. Does C#/Roslyn team plan to provide us some workaround at least for allocation issue related to the use of Invariant(?

from csharplang.

gafter avatar gafter commented on July 17, 2024

@nanoant I haven't heard any proposals that fit the bill. If it is a change of language you're looking for, this belongs in the csharplang repo.

from csharplang.

iam3yal avatar iam3yal commented on July 17, 2024

dup #177

from csharplang.

tofalck avatar tofalck commented on July 17, 2024

Perhaps a syntax like below could be used in that it would use the one set right after $, and let any of the placeholder override the default per needs?

This would align with the current overall syntax and enable in-string flexibility?

$:en-US"?latitude={lat:F4}&longitude={lon:F4}&amount={amount:C:da-DK}"
$:env"?latitude={lat:F4:invariant}&longitude={lon:F4:invariant}&amount={amount:C}"

from csharplang.

tofalck avatar tofalck commented on July 17, 2024

Not quite the same kind of flexibility and syntactic sugar though...

from csharplang.

ufcpp avatar ufcpp commented on July 17, 2024

It is more painful to lose CultureInfo in nested interpolation rather than the length of the code.
#6882

from csharplang.

julealgon avatar julealgon commented on July 17, 2024

This requirement to me feels like it would need the exact same underlying mechanism as collection literals would for allowing the passing of constructor parameters.

If a syntax such as the one I mentioned there was put in place, it would be general enough to apply to interpolation as well:

$"{somevalue}"(CultureInfo.InvariantCulture)

Or

$"{somevalue}" with (CultureInfo.InvariantCulture)

@TahirAhmadov This is why I was pushing so much for orthogonality in that other thread. Here we have another very similar situation where a common syntax would be greatly beneficial. You dismissed my suggested general syntax by saying this:

I can't see the need for a special literal syntax for these types.

But here we are. This is basically the exact same problem, but with interpolated literals. A syntax that was specific for collection literals would not work here and would force a different syntax for passing constructor-like arguments.

from csharplang.

CyrusNajmabadi avatar CyrusNajmabadi commented on July 17, 2024

the idea of special syntax for these different feature areas is that htey benefit from dedicated syntax per-domain. For example, one could think of an string as a collection of characters. That doesn't mean the same syntax for collection-exprs is what we want for strings. When something is important enough, we actually go away from uniform syntax to specialized syntax.

It's very possible that will be true here as well.

IMO, for one, i absolutely do not want collection-exprs bogged down by a heavyweight syntax for arguments. The idea behind collection-exprs is for syntactic overhead to be at an absolute minimum. That's why, for example, we are not going with [ [k] = v ] for dictionaries, even though we use [k] = v in object initializers. We genuinely don't want hte syntax to be as heavyweight as that.

from csharplang.

julealgon avatar julealgon commented on July 17, 2024

the idea of special syntax for these different feature areas is that htey benefit from dedicated syntax per-domain. For example, one could think of an string as a collection of characters. That doesn't mean the same syntax for collection-exprs is what we want for strings.

Well I can speak for myself that the reason I suggested the general syntax was not based on that at all... it was just to make sure the new "capability" of allowing to pass extra parameters for short-hand/literals was as orthogonal as possible in the language and could be used consistently in as many cases as possible.

The fact it fits (IMHO) this case here is just a consequence of that, of it being orthogonal.

When something is important enough, we actually go away from uniform syntax to specialized syntax.

Fair enough, but I just don't see the reason to create dedicated syntax in this (these) particular cases when there are alternatives that are just as clean that apply globally.

IMO, for one, i absolutely do not want collection-exprs bogged down by a heavyweight syntax for arguments.

Is this really heavyweight though? It's an extra parenthesis with the desired value... there are like 2 extra characters other than the actual intent there.

$"{somevalue}"(CultureInfo.InvariantCulture)

Yet here we have proposals for weird stuff like $i"{somevalue}"... that's so specific though. What about even other cultures? Are we adding a single-letter identifier for each one? What if I create my own CultureInfo object and want to pass that in? Now that would not be possible? Why create such a limiting syntax for something that takes an unbounded number of arguments in the first place.

Maybe we could even go one step further and come up with something like "implicit static using" and allow this without an explicit static using at the top of each file:

$"{somevalue}"(InvariantCulture)

Can you get more concise than that without being limiting and cryptic?

from csharplang.

colejohnson66 avatar colejohnson66 commented on July 17, 2024

#177 (comment)

from csharplang.

julealgon avatar julealgon commented on July 17, 2024

@colejohnson66 were you trying to make some point? Can you elaborate?

from csharplang.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.