Thanks for the update! I’m writing comments as I read, so if I haven’t changed this text it’s because I forgot (or I hit “Reply” early) and there’ll be a summary at the end. here’s my summary: I’m happy with basically everything, have some comments about where types should go, and am pretty sure there’s a better way to handle the interleaved args but I’m not totally convinced which way to go with it.
- The Template Type
I expect this type will be internal to the interpreter (in CPython’s case, a native type), and so putting an isinstance-able version in types is fine. Don’t define it in terms of @dataclass though, even with the caveat. We can’t implement it in terms of that, so better to specify it directly.
Of course, if Template is going to be directly instantiable, we’re (a) going to have to be okay with the added overhead and (b) it probably doesn’t live in types anymore, just because we shouldn’t have to import types (even implicitly) in order to use a t-string. But if type(t"") is not Template is acceptable (assuming isinstance(t"", Template) is still True), then I guess the types definition can be a duck-type equivalent.
I much prefer always using Interpolation and not alternating with str. Interested what others think about that, but as a consumer I’d prefer to not have to type check - either I can assume that .value is meaningful, or str() is some reasonable default behaviour.
Alternatively, if they always come in (literal, interpolation) pairs, where literal may be an empty string and interpolation may be None/falsey. Then I can for s, v in t.args:, rather than type checking or coming up with some kind of alternating iteration.
(Side thought: if Template.__str__ applies normal formatting rules to each interpolation, then in many cases t-strings and f-strings could be interchangeable…)
- Concatenation
Why not? It’s just concatenating .args isn’t it?
- The debug specifier (
=)
I’m not convinced about this. Perhaps we should just forbid it here? Or maybe it needs to move into the grammar in a way that lets us pass it through as a conversion flag or its own flag?
- Interleaving …
Ah, structural pattern matching gets a mention. If this was earlier, I’d have been less concerned about the interleaved approach. It feels a bit clunky? I wonder if there’s a design more geared towards match that would feel smoother?
In short, my feeling here is that designing specifically for “you should use match” is fine, and so is “you should not use match”, and we’re in a weird kind of middle ground right now where neither approach feels great. (But maybe others will come in and say the match approach does feel great, and it’s just me, which is totally likely! In this case, please put it as the first example rather than the last one.)