C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Supporting f-strings in C++

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Sat, 14 Oct 2023 23:50:14 -0400
On Sat, Oct 14, 2023 at 11:40 PM Hadriel Kaplan via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> > From: Barry Revzin <barry.revzin_at_[hidden]>
>
> > You can't do that though, since you can already call std::print, etc., with
> > just a string literal - and the meaning of std::print with just a format
> > string is distinct from the meaning of what you're suggesting calling
> > std::print with a std::string would be. For instance, std::print("X{{}}")
> > is a valid call today - which prints "X{}" - because we always interpret
> > the first argument as a format string. If we add this overload, it would
> > suddenly print "X{{}}", because we would interpret the argument as just a
> > string.
>
> We could define a new overload such as emulated here: https://godbolt.org/z/rd8x6GdaK
>
> But that would change the matching-function `print("foo")` previously invoked, and I don't know if that means it's an ABI-break (a non-starter obviously).
>
> And to be clear: I'm not proposing such a change would be part of this proposal - it would be a separate proposal, if done at all. It just seemed silly to me that both print() and println() _require_ the format-string to be known at compile-time. I guess that's why vprint_unicode() exists, but it's awkward.
>
>
> > This isn't a good argument though, because while std::print does write to
> > stdout, not all uses of the format API do. format_to() doesn't.
>
> Actually, after some more thought, I don't think `format_to()` should change to support taking a string anyway. I mean the function _is_ named "FORMAT_to()" after all - it's for the purpose of formatting.
>
> You don't ever need to use such a function if you have a resolved string already, so you wouldn't use it with an f-string either.
>
> You could just do `*out = F"x={x}";` and be done, no?
>
>
> > Not all uses of the format API are even formatting synchronously - some simply do
> > type-checking in the front end and serialize their arguments to be
> > formatted later. For such uses, an extra temporary string is a complete
> > non-starter.
>
> That's _ok_. F-strings aren't a replacement for formatting-functions, nor even completely for std::format. There are various things that std::format can do that an f-string cannot.
>
> Just like in python they weren't a complete replacement for str.format() either. And yet they're extremely popular.
>
> F-strings are just a convenience to improve argument-usage visibility, and to be less verbose. They're usable in the most common use-cases, which is why they're still useful despite limitations.

But why? The advantages of having an F-string turn into a sequence of
arguments that can be consumed by any number of functions (those
currently existing and those yet to be written) are pretty
substantial. It would have no coupling to a specific API, it would be
usable in far more scenarios, etc. The *only* downside is that your
"most common use-cases" needs to have `std::format()` explicitly
wrapped around it.

Personally, I prefer it if everyone can have their own "most common
use-cases", rather than forcing everyone to use one specific API if
they want the advantages of F-strings. Also, the point that Rust does
something similar is pretty significant.

Received on 2023-10-15 03:50:37