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

Peter Ludemann pludemann at google.com
Mon Aug 17 07:58:09 CEST 2015


How is this proposal of di"..." more than a different spelling of lambda
i"..."? (I think it's a great idea — but am wondering if there are some
extra semantics that I missed)

I don't think there's any need to preserve the values of the {...} (or
${...}) constituents — the normal closure mechanism should do fine because
logging is more-or-less like this:
   if <conditions for logging>:
     if callable(msg):
       log_msg = msg(*args)
     else:
       log_msg = msg % args
and so there's no need to preserve the values at the moment the
interpolated string is created.

Perl allows arbitrary expressions inside interpolations, but that tends to
get messy and is self-limiting for complex expressions; however, it's handy
for things like:
   print("The {i+1}th item is strange: {x[i]})


On 16 August 2015 at 13:04, Gregory P. Smith <greg at krypto.org> wrote:

>
>
> 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/c7c89953/attachment.html>


More information about the Python-Dev mailing list