C++ Logo

std-proposals

Advanced search

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

From: Barry Revzin <barry.revzin_at_[hidden]>
Date: Sat, 14 Oct 2023 10:37:35 -0500
On Fri, Oct 13, 2023 at 5:58 AM Hadriel Kaplan via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Back in 2019, https://wg21.link/p1819r0 was submitted for "interpolated
> literals". I believe it was reviewed in EWG-Incubator back then, and again
> in 2022. There appears to have been consensus for the author to keep
> working on it generally, but no consensus on the proposal's specific
> details.
>
> I'd like to propose a different solution - but only for the specific idea
> of having f-strings in C++, as opposed to a general string-interpolation
> framework.
>
> I've written up a brief strawman here: https://tinyurl.com/3tr8rv22
>
> The basic idea is to just syntactically replace an f-string with its
> std::format() counterpart, as a new step between phase 6 and 7 of
> translation, right after concatenation of string-literals. I.e., an
> f-string would just be syntactic-sugar for std::format().
>
> More-detailed rules are written in the linked proposal above. It even
> includes a way to add a customization point should that be desired by the
> WG, at which point it's a form of interpolation and could perhaps fully
> replace P1819.
>
> It's arguably a bit hacky, but it should be far simpler than P1819 to
> implement, use, and maybe even standardize.
>
> I'm looking for feedback on whether this is an idea worth pursuing, or
> whether it's a horrible idea and I should never raise it again.
>
> -hadriel
>

I think this approach is kind of a non-starter. We can't have f"x={x}" just
mean std::format("x={}", x) for an important reason.

This means that std::print(f"x={x}") doesn't and can't work - which is the
sort of thing that seems important to support - having to write
std::print("{}", f"x={x}") is... less than ideal.

More generally, the issue is that there are a lot of uses of the format API
that are not literally std::format(). In the standard we have std::print(),
std::format_to(), etc. It would be really nice if those worked with
f-strings as well. But even outside of the standard, we have all sorts of
logging frameworks that would really want to be able to benefit from this
feature in a nice way. For instance, let's say you use spdlog - which is
one of the (if not the) most popular - you would really want to be able to
write spdlog::info(f"x={x}") too, and have that work too.

This is why I think the more viable approach is to have f-strings expand
into something like an expression list. So f"x={x}" literally just
evaluates as "x={}", x - so that wrapping it in a function call works. That
is, std::format(f"x={x}") simply evaluates as std::format("x={}", x).
Probably with the added requirement that it must be wrapped in a function
call or something. That means that, yes, you have to write
std::format(f"x={x}") if you just want the string, which is more verbose
than what you're proposing. But that seems fine to me - I'm not sure the
Rust community is complaining a lot about having to write format!("x={x}"),
for instance. And it's still less verbose than what we write today and
being more clear. Python gets away with f"..." just giving you a string
because, well... it's Python so whatever, you just get a string.

Barry

Received on 2023-10-14 15:37:52