
On 2015-07-23 15:22, Steven D'Aprano wrote:
On Wed, Jul 22, 2015 at 09:28:19PM -0700, Bruce Leban wrote:
On Wed, Jul 22, 2015 at 8:31 PM, Steven D'Aprano <steve@pearwood.info> wrote:
Constant-folding 'a' + 'b' to 'ab' is an optimization, it doesn't change the semantics of the concat. But constant-folding f'{a}' + '{b}' would change the semantics of the concatenation, because f strings aren't constants, they only look like them.
It doesn't have to change semantics and it shouldn't. This is a strawman argument.
If I had a dollar for everytime somebody on the Internet misused "strawman argument", I would be a rich man. Just because you disagree with me or think I'm wrong doesn't make my argument a strawman. It just makes me wrong-headed, or wrong :-)
I'm having trouble understand what precisely you are disagreeing with. The example I give which you quote involves explicit concatenation with the + operator, but your examples below use implicit concatenation with no operator at all.
Putting aside the question of implementation, I think:
(1) Explicit concatenation with the + operator should be treated as occuring after the f strings are evaluated, *as if* the following occurs:
f'{spam}' + '{eggs}' => compiles to format(spam) + '{eggs}'
If you can come up with a clever optimization that avoids the need to *actually* build two temporary strings and then concatenate them, I don't have a problem with that. I'm only talking about the semantics. I don't want this:
f'{spam}' + '{eggs}' => compiles to format(spam) + format(eggs) # not this!
Do you agree with those semantics for explicit + concatenation? If not, what behaviour do you want?
(2) Implicit concatenation should occur as early as possible, before the format. Take the easy case first: both fragments are f-strings.
f'{spam}' f'{eggs}' => behaves as if you wrote f'{spam}{eggs}' => which compiles to format(spam) + format(eggs)
Do you agree with those semantics for implicit concatenation?
To me, implicit concatenation is just concatenation that binds more tightly, so: 'a' 'b' is: ('a' + 'b') It can be optimised to 'ab' at compile-time.
(3) The hard case, when you mix f and non-f strings.
f'{spam}' '{eggs}'
Notwithstanding raw strings, the behaviour which makes sense to me is that the implicit string concatenation occurs first, followed by format. So, semantically, if the parser sees the above, it should concat the string:
=> f'{spam}{eggs}'
then transform it to a call to format:
=> format(spam) + format(eggs)
To me: f'{spam}' '{eggs}' is: (f'{spam}' + '{eggs}') just as: r'\a' '\\' is: (r'\a' + '\\') [snip]