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 12:20:13 -0400
On Sat, Oct 14, 2023 at 11:37 AM Barry Revzin via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> 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

Note that this also immediately resolves the question of whether it's
a good idea to couple the language to something as big and mercurial
(and perhaps inefficient) as `std::format`. Even though it obviously
expects to be used by something that can *speak* `std::format`, the
fact that it does not directly use `std::format` is a win.

Received on 2023-10-14 16:20:36