[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