On Tue, Aug 30, 2016 at 11:43:03PM +1000, Chris Angelico wrote: > On Tue, Aug 30, 2016 at 10:56 PM, Philipp A. <flying-sh...@web.de> wrote: > > My issue is just that it’s as much of a string as a call of a (string > > returning) function/method or an expression concatenating strings: > > > > ''.join(things) # would you call this a string? > > '{!r}'.format(x) # or this? it’s basically the same as this “f-string”: > > f'{x!r}' > > 'start' + 'end' # or this? it’s a concatenation of two strings, just like > > f'start{ "end" }' > > Yes, an f-string is really a form of expression, not a literal. But > prior art has generally been to have similar constructs referred to as > "interpolated strings" or similar terms: > > https://en.wikipedia.org/wiki/String_interpolation
*shrug* A misleading name is misleading no matter how many people use it. If <insert the name of a language you dislike here> started calling function calls: func(arg, x, y, z+1) "s-strings" for "source code strings", because you write them as source code, and changed the syntax to func"arg, x, y, z+1" we'd all recognise what a mistake it is to call this a string, string delimiters or not. The *result* of calling it may be a string, but the expression itself is a kind of function call. [nasty thought] Why don't we allow func"*args" as syntactic sugar for str(func(*args))? [/remove tongue from cheek] > Plenty of languages have some such feature, and it's usually > considered a type of string. The result is a type of string. The expression is not. > Notice the close parallels between actual > string literals used as format strings ("I have %d apples" % apples) > and f-strings (f"I have {apples} apples"), That's a misleading comparison. The *template string* is "I have %d apples" and that is just a string. The *format operator* is % and the formatting operation or expression is the entire expression. Since f-strings can contain arbitrary expressions, the analogy is not with the template string, but a function (method or operator) call: f"I have {fruit - bananas - oranges} apples" is not equivalent to "I have {} apples", but to "I have {} apples".format(fruit - bananas - oranges) which is clearly a method call that merely returns a string, not a string itself. Consequently, there's no way to delay evaluation of such an f-string, any more than you can delay evaluation of the expression[1]: func(fruit, 2*bananas, 3/oranges) You can't generate a template, and pass it to different environments to be formatted. If you need to evaluate f"I have {apples} apples" in six different contexts, you have to repeat yourself: it is equivalent to a function call, complete with implicit arguments, not a function object, and certainly not equivalent to a template string. > and how this same parallel > can be seen in many other languages. Yes, it may be a join expression > to the compiler, but it's a string to the programmer. Only if the programmer is fooled by the mere use of string delimiters. It really isn't a string. It is executable code that returns a string. It is basically a distant cousin to eval(), in disguise. I really wish we had a better name for these things than f-strings :-( [1] Tricks with eval() excluded. -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/