C++ Logo

std-proposals

Advanced search

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

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Mon, 16 Oct 2023 14:31:02 +0200
pon., 16 paź 2023 o 13:37 Marcin Jaczewski
<marcinjaczewski86_at_[hidden]> napisał(a):
>
> pon., 16 paź 2023 o 11:37 Sebastian Wittmeier via Std-Proposals
> <std-proposals_at_[hidden]> napisał(a):
> >
> > Hi Hadriel,
> >
> > I really have not known, whether it was working with the preprocessor, without reading up and trying out.
> >
> >
> >
> > I think that topic belongs slightly together with the escaping/delimiter discussion and there are five basic options to activate the preprocessor:
> >
> >
> >
> > A) Each (or only the more complex) C++ expression leave the F string and resume it, everything is concateated, e.g.:
> >
> > print( X"SOME_FLAG = {" SOME_FLAG ":x}" );
> >
> > - easier to include the preprocessor without preprocessing time parsing
> >
> > - proliferation of quotes/unquotes
> >
> > - looks more like the iostream way, when we add + or even << in between
> >
> >
> >
> > B) simple specific escaping
> >
> > print( X"SOME_FLAG = { ####SOME_FLAG####:x }" );
> >
> > - the part between #### #### is handled by the preprocessor, although it is within a X/R string
> >
> > - also helps with colon
> >
> > - possible to forget for generic code, except if #### required for all {} expressions, e.g. a l-value identifier could be a preprocessor redefined symbol
> >
> > - so either it is required every time (no simple {lvalue} possible anymore) or it is only used, when needed and will be often forgotten or other code changes (SOME_FLAG is suddenly a preprocessor define) that would require it
> >
> >
> >
> > C) complete escaping
> >
> > print( X"SOME_FLAG = { a ? \"\\\\\" \\: \"\\:\" :x }" ); // for a ? "\" : ":"
> >
> > - certain characters are escaped: '"', '\', '}', ':'
> >
> > - not easy to read
> >
> > - better (?) than heuristics with additional paranthesis, which only sometimes work
> >
> >
> >
> > D) Flexible escaping similar to raw string literals
> >
> > print( X"SOME_FLAG = {dch{ a ? b : c :dchx }dch" );
> >
> > - with dch a delim character sequence, which can be freely chosen
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > E) have the preprocessor parse the string itself
> >
> > print( X"SOME_FLAG = { SOME_FLAG:x}" );
> >
> > - most difficult to sync WG21/WG14
> >
> >
>
> Another case to consider:
> ```
> auto x = Obj{ true ? 1 : 2}; //valid code
> auto y = X" test { Obj{ true ? 1 : 2} }"; //valid?
> auto y = X" test { Obj{ (true ? 1 : 2)} }"; //valid?
> auto y = X" test { (Obj{ true ? 1 : 2}) }"; //valid?
> ```
>

After some thinking, as preprocessors can convert tokens into string
using `#s` operator, why not allow the opposite?
Image new buildin macro function `__EXTRACT_PARSE(str)` that conver
`"{x} {y}"` string into sequence of tokens `"{} {}", x, y`.
This fix lot of corner cases and how it will interact with macros and
even allow C compatibility.
You could define even monstority like:
```
__EXTRACT_PARSE("{__EXTRACT_PARSE(\"{x}\")}") // -> "{}",
__EXTRACT_PARSE("{x}") -> "{}", "{}", x
```
It will follow simple rules of balanced `{}()[]'"` when parsing and
output tokes as is.
As its normal string then normal string rules apply, like:
```
__EXTRACT_PARSE("foo {a" "b}") //-> "foo {}", ab
__EXTRACT_PARSE(R"(foo {a" "b})") //-> "foo {}", a " " b
```



> >
> > -----Ursprüngliche Nachricht-----
> > Von: Hadriel Kaplan <hkaplan_at_[hidden]>
> > Gesendet: So 15.10.2023 18:45
> > Betreff: Re: [std-proposals] Supporting f-strings in C++: draft-R1
> > An: std-proposals_at_[hidden];
> > CC: Sebastian Wittmeier <wittmeier_at_[hidden]>;
> > > From: Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf of Sebastian Wittmeier via Std-Proposals <std-proposals_at_[hidden]>
> >
> > > you write that there is no preprocessor support within the f-strings.
> > > Is it possible to concatenate preprocessor macro results with preprocessor string concatenation?
> > > If yes, would it be further possible to have the preprocessor preprocess code in its usual way, put it through a STRINGIFY macro and concatenate it into the f string?
> >
> > You can use preprocessor macros to stringify other macro expansions as you can do today, of course - but as far as I know the preprocessor cannot concatenate two string literals into one token literal using the `##`. It's usually the phase-6 translation right afterwards that concatenates them instead.
> >
> > So then I don't see how you'd get it to become an f-string, since presumably you'd want to join multiple stringified literals into one final f-string.
> >
> > For just _one_ stringified macro I think you can do it, but that doesn't seem useful.
> >
> > I.e., you might be able to get a stringified `__LINE__` for line 42 to become a `F"42"`, but if you wanted it to become `F"{42:x}"` instead, I don't think that's possible. (though I'm no PP expert)
> >
> > I mean basically think of the `F"..."` or `X"..."` as being similar to `R"(...)"` in terms of tokens, and you can try to create an `R"(...)"` using the preprocessor today to see if it's possible - I don't think it is, but I might be wrong. If it _is_ possible then it should be possible to do for f-strings too.
> >
> > ---
> >
> > Or maybe I misunderstand you - are you instead saying: "I know macro-magic won't work with f-strings as defined, but can the proposal define some way for it to work?"
> >
> > -hadriel
> >
> >
> >
> > Juniper Public
> >
> >
> >
> > --
> > Std-Proposals mailing list
> > Std-Proposals_at_[hidden]
> > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2023-10-16 12:31:15