Currently, Python has (among other ways) two different systems that handle {}-based string interpolation: you can make an ordinary string and call its `.format` method later to interpolate the values explicitly, or you can use an f-string. The advantage of f-strings, which justifies the implicit nature, is that they're far more convenient and avoid redundancy. But the disadvantage is that they don't allow for either deferring the interpolation or intercepting the interpolated values. The f-string is basically transformed, at compile time, into code that would assemble the string described; and that code runs immediately, using the current environment (all accessible variable scopes).
In the proposed new reality, a t-string is also transformed at compile time, but it transforms into an instance of some new library class which acts as a container for the parsed string contents. For example, something like
t'Example {template!r} string with {2.00:g} placeholders'
. Of course, these examples are only illustrative; the actual transformation occurs at an AST level, not a source code level. It also doesn't actually use those operators and function calls; f-strings have special support in the form of `FORMAT_VALUE` and `BUILD_STRING` opcodes.)
Then, user code can import from the standard library for the type names (it will probably also need `Interpolation` defined at runtime to do `isinstance` checks) and transform the `Template` into a string following whatever custom logic it likes. Or, indeed, into any other object; the usual dynamic typing rules apply. When the transformation function is called, the Template already embeds the variable values, so they don't need to be passed (unlike with the `.format` method), but no actual string assembly has been done yet (unlike with an f-string). So there is a complete separation of concerns between what is interpolated and how the interpolation is done, but still no need to specify the "what" explicitly (i.e. redundantly with the placeholder names) - and the default "how" is not privileged.
(Hopefully it's obvious why t-strings wouldn't be able to benefit from bytecode optimizations like f-strings do.)
As a personal observation, the kinds of compile-time transformation involved in both f-strings and the proposed t-strings could be seen as special cases of what the far-reaching "Syntactic Macros" PEP (https://peps.python.org/pep-0638/) hopes to offer (but hard-coded and not using a special macro syntax).
1 comment
[ 5.5 ms ] story [ 14.6 ms ] threadCurrently, Python has (among other ways) two different systems that handle {}-based string interpolation: you can make an ordinary string and call its `.format` method later to interpolate the values explicitly, or you can use an f-string. The advantage of f-strings, which justifies the implicit nature, is that they're far more convenient and avoid redundancy. But the disadvantage is that they don't allow for either deferring the interpolation or intercepting the interpolated values. The f-string is basically transformed, at compile time, into code that would assemble the string described; and that code runs immediately, using the current environment (all accessible variable scopes).
In the proposed new reality, a t-string is also transformed at compile time, but it transforms into an instance of some new library class which acts as a container for the parsed string contents. For example, something like
turns into something like at compile time. (For comparison, the corresponding f-string would turn into something like . Of course, these examples are only illustrative; the actual transformation occurs at an AST level, not a source code level. It also doesn't actually use those operators and function calls; f-strings have special support in the form of `FORMAT_VALUE` and `BUILD_STRING` opcodes.)Then, user code can import from the standard library for the type names (it will probably also need `Interpolation` defined at runtime to do `isinstance` checks) and transform the `Template` into a string following whatever custom logic it likes. Or, indeed, into any other object; the usual dynamic typing rules apply. When the transformation function is called, the Template already embeds the variable values, so they don't need to be passed (unlike with the `.format` method), but no actual string assembly has been done yet (unlike with an f-string). So there is a complete separation of concerns between what is interpolated and how the interpolation is done, but still no need to specify the "what" explicitly (i.e. redundantly with the placeholder names) - and the default "how" is not privileged.
(Hopefully it's obvious why t-strings wouldn't be able to benefit from bytecode optimizations like f-strings do.)
As a personal observation, the kinds of compile-time transformation involved in both f-strings and the proposed t-strings could be seen as special cases of what the far-reaching "Syntactic Macros" PEP (https://peps.python.org/pep-0638/) hopes to offer (but hard-coded and not using a special macro syntax).