[Python-ideas] Briefer string format
Steven D'Aprano
steve at pearwood.info
Sat Jul 25 05:51:50 CEST 2015
On Fri, Jul 24, 2015 at 07:02:49PM +0200, Sven R. Kunze wrote:
> My semantic opinion on this: first format, then concat. Why? Because
> '...' is a atomic thing and shouldn't be modified by its peer elements
> (i.e. strings).
Implicit concatenation is a lexical feature, not a runtime feature.
Every other case of implicit concatenation in Python occurs at compile-
time, and has since Python 1.5 if not earlier. This would be an
exception, and would occur after the function call. That's surprising
and inconsistent with all the other examples of implicit concatenation.
'aaa' 'bbb'.upper()
returns 'AAABBB', not 'aaaBBB'.
> About implementation: the idea of first concat with **implicit**
> escaping braces illustrated another minor use case for me: no need to
> escape braces.
>
> f'Let {var} = ''{x | x > 3}'
Sorry, I find that really hard to parse without a space between the two
fragments, so let me add a space:
f'Let {var} = ' '{x | x > 3}'
That's better :-)
I completely understand the appeal of your point of view. But it feels
wrong to me, I think that it mixes up syntactical features and runtime
features inappropriately.
If we write
f'{spam}'
that's syntactic sugar for a call to the format method:
'{spam}'.format(***)
where the *** stands in for some sort of ChainMap of locals, nonlocals,
globals and built-ins, purely for brevity, I'm not implying that should
be new syntax. Since *in all other cases* implicit concatenation occurs
before runtime method or function calls:
f'{spam}' '{eggs}'
should be seen as:
# option (1)
'{spam}' '{eggs}' . format(***)
not
# option (2a)
'{spam}' . format(***) + '{eggs}'
I'm not implying that the *implementation* must involve an explicit
concat after the format. It might, or it might optimize the format
string by escaping the braces and concat'ing first:
# option (2b)
'{spam}{{eggs}}' . format(***)
Apart from side-effects like time and memory, options (2a) and (2b) are
equivalent, so I'll just call it "option (2)" and leave the
implementation unspecified.
I think that option (2) is surprising and inconsistent with all other
examples of implicit concatenation in Python.
I think that *predictability* is a powerful virtue in programming
languages, special cases should be avoided if possible. Option (1)
follows from two facts:
- implicit concatenation occurs as early as possible (it is a lexical
feature, so it can occur at compile-time, or as close to compile-time
as possible);
- f strings are syntactic sugar for a call to format() which must be
delayed to run-time, as late as possible.
These two facts alone allow the programmer to reason that
f'{spam}' '{eggs}'
must be analogous to the case of 'aaa' 'bbb'.upper() above.
Option (2) requires at least one of the two special cases:
- implicit concatenation occurs as early as possible, unless one of the
strings is a f string, in which case it occurs... when exactly?
- literal strings like '{eggs}' always stand for themselves, i.e. what
you see is what you get, except when implicitly concatenated to f
strings, where they are magically escaped.
We already have at least two other ways to get the same result that
option (2) gives:
f'{spam}' + '{eggs}' # unambiguously format() first, concat second
f'{spam}{{eggs}}' # unambiguously escaped braces
Giving implicit concatenation a special case just for convenience sake
would, in my opinion, make Python just a little more surprising for
little real benefit.
--
Steve
More information about the Python-ideas
mailing list