[Python-Dev] PEP-498 & PEP-501: Literal String Formatting/Interpolation

Gregory P. Smith greg at krypto.org
Sun Aug 16 22:04:09 CEST 2015


On Sun, Aug 9, 2015 at 3:25 PM Brett Cannon <brett at python.org> wrote:

>
> On Sun, Aug 9, 2015, 13:51 Peter Ludemann via Python-Dev <
> python-dev at python.org> wrote:
>
> Most of my outputs are log messages, so this proposal won't help me
> because (I presume) it does eager evaluation of the format string and the
> logging methods are designed to do lazy evaluation. Python doesn't have
> anything like Lisp's "special forms", so there doesn't seem to be a way to
> implicitly put a lambda on the string to delay evaluation.
>
> It would be nice to be able to mark the formatting as lazy ... maybe
> another string prefix character to indicate that? (And would the 2nd
> expression in an assert statement be lazy or eager?)
>
>
> That would require a lazy string type which is beyond the scope of this
> PEP as proposed since it would require its own design choices, how much
> code would not like the different type, etc.
>
> -Brett
>

Agreed that doesn't belong in PEP 498 or 501 itself... But it is a real
need.

We left logging behind when we added str.format() and adding yet another
_third_ way to do string formatting without addressing the needs of
deferred-formatting for things like logging is annoying.

brainstorm: Imagine a deferred interpolation string with a d'' prefix..
 di'foo ${bar}' would be a new type with a __str__ method that also retains
a runtime reference to the necessary values from the scope within which it
was created that will be used for substitutions when iff/when it is
__str__()ed.  I still wouldn't enjoy reminding people to use di''
inlogging.info(di'thing happened: ${result}') all the time any more than I
like reminding people to undo their use of % and just pass the values as
additional args to the logging call... But I think people would find it
friendlier and thus be more likely to get it right on their own.  logging's
manually deferred % is an idiom i'd like to see wither away.

There's also a performance aspect to any new formatter, % is oddly pretty
fast, str.format isn't. So long as you can do stuff at compile time rather
than runtime I think these PEPs could be even faster. Constant string
pep-498 or pep-501 formatting could be broken down at compile time and
composed into the optimal set of operations to build the resulting string /
call the formatter.

So far looking over both peps, I lean towards pep-501 rather than 498:

I really prefer the ${} syntax.
I don't like arbitrary logical expressions within strings.
I dislike str only things without a similar concept for bytes.

but neither quite suits me yet.

501's __interpolate*__ builtins are good and bad at the same time.  doing
this at the module level does seem right, i like the i18n use aspect of
that, but you could also imagine these being methods so that subclasses
could override the behavior on a per-type basis.  but that probably only
makes sense if a deferred type is created due to when and how interpolates
would be called.  also, adding builtins, even __ones__ annoys me for some
reason I can't quite put my finger on.

(jumping into the threads way late)
-gps

>
> PS: As to Brett's comment about the history of string interpolation ... my
> recollection/understanding is that it started with Unix shells and the
> "$variable" notation, with the "$variable" being evaluated within "..." and
> not within '...'. Perl, PHP, Make (and others) picked this up. There seems
> to be a trend to avoid the bare "$variable" form and instead use
> "${variable}" everywhere, mainly because "${...}" is sometimes required to
> avoid ambiguities (e.g. "There were $NUMBER ${THING}s.")
>
> PPS: For anyone wishing to improve the existing format options, Common
> Lisp's FORMAT <http://www.gigamonkeys.com/book/a-few-format-recipes.html>
> and Prolog's format/2
> <https://quintus.sics.se/isl/quintus/html/quintus/mpg-ref-format.html>
> have some capabilities that I miss from time to time in Python.
>
> On 9 August 2015 at 11:22, Eric V. Smith <eric at trueblade.com> wrote:
>
> On 8/9/2015 1:38 PM, Brett Cannon wrote:
> >
> >
> > On Sun, 9 Aug 2015 at 01:07 Stefan Behnel <stefan_ml at behnel.de
>
> > <mailto:stefan_ml at behnel.de>> wrote:
> >
> >     Eric V. Smith schrieb am 08.08.2015 um 03:39:
> >     > Following a long discussion on python-ideas, I've posted my draft
> of
> >     > PEP-498. It describes the "f-string" approach that was the subject
> of
> >     > the "Briefer string format" thread. I'm open to a better title than
> >     > "Literal String Formatting".
> >     >
> >     > I need to add some text to the discussion section, but I think
> it's in
> >     > reasonable shape. I have a fully working implementation that I'll
> get
> >     > around to posting somewhere this weekend.
> >     >
> >     > >>> def how_awesome(): return 'very'
> >     > ...
> >     > >>> f'f-strings are {how_awesome()} awesome!'
> >     > 'f-strings are very awesome!'
> >     >
> >     > I'm open to any suggestions to improve the PEP. Thanks for your
> >     feedback.
> >
> >     [copying my comment from python-ideas here]
> >
> >     How common is this use case, really? Almost all of the string
> formatting
> >     that I've used lately is either for logging (no help from this
> proposal
> >     here) or requires some kind of translation/i18n *before* the
> formatting,
> >     which is not helped by this proposal either. Meaning, in almost all
> >     cases,
> >     the formatting will use some more or less simple variant of this
> >     pattern:
> >
> >         result = process("string with {a} and {b}").format(a=1, b=2)
> >
> >     which commonly collapses into
> >
> >         result = translate("string with {a} and {b}", a=1, b=2)
> >
> >     by wrapping the concrete use cases in appropriate helper functions.
> >
> >     I've seen Nick Coghlan's proposal for an implementation backed by a
> >     global
> >     function, which would at least catch some of these use cases. But it
> >     otherwise seems to me that this is a huge sledge hammer solution for
> a
> >     niche problem.
> >
> >
> > So in my case the vast majority of calls to str.format could be replaced
> > with an f-string. I would also like to believe that other languages that
> > have adopted this approach to string interpolation did so with knowledge
> > that it would be worth it (but then again I don't really know how other
> > languages are developed so this might just be a hope that other
> > languages fret as much as we do about stuff).
>
> I think it has to do with the nature of the programs that people write.
> I write software for internal use in a large company. In the last 13
> years there, I've written literally hundreds of individual programs,
> large and small. I just checked: literally 100% of my calls to
> %-formatting (older code) or str.format (in newer code) could be
> replaced with f-strings. And I think every such use would be an
> improvement.
>
> I firmly believe that the majority of software written in Python does
> not show up on PyPi, but is used internally in corporations. It's not
> internationalized or localized: it just exists to get a job done
> quickly. This is the code that would benefit from f-strings.
>
> This isn't to say that there's not plenty of code where f-strings would
> not help. But I think it's as big a mistake to generalize from my
> experience as it is from Stefan's.
>
> Eric.
>
>
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
>
>
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/pludemann%40google.com
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
>
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/brett%40python.org
>
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/greg%40krypto.org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20150816/b37ec2b3/attachment-0001.html>


More information about the Python-Dev mailing list