<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Aug 12, 2015 at 6:06 PM, Barry Warsaw <span dir="ltr"><<a href="mailto:barry@python.org" target="_blank">barry@python.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">[...]<br>On Aug 12, 2015, at 08:50 AM, Guido van Rossum wrote:<br>
</span><span class="">>It also has the same problems as locals(), sys._getframe(), etc., which is<br>
>that their presence makes certain optimizations harder (in IronPython IIRC<br>
>the creation of frame objects is normally skipped to speed up function<br>
>calls, but the optimizer must detect the presence of those functions in<br>
>order to disable that optimization). That doesn't mean I'm opposed to it (I<br>
>don't have a problem with locals()), but it does mean that I think their<br>
>use should probably not be encouraged.<br>
<br>
</span>I'm much less concerned about the performance impact loss of optimization<br>
provides because I think i18n is already generally slower... and that's okay!<br>
I mean _() has to at least do a dictionary look (assuming the catalog is<br>
warmed in memory) and then a piece-wise interpolation into the resulting<br>
translated string.  So you're already paying runtime penalty to do i18n.<span class=""><br></span></blockquote><div><br></div><div>Fair enough. (Though IMO the real cost of i18n is that it introduces a feeling of programming in molasses.)<br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">[...]</span><br>
i18n is one of those places where DRY really is a limiting factor.  You just<br>
can't force coders to pass in all the arguments to their translated strings,<br>
say into the _() function.  The code looked horrible, it's way too much<br>
typing, and people (well, *I* ;) just won't do it.  After implementing the<br>
sys._getframe() hack, it made i18n just so much more pleasant and easy to<br>
write, you almost couldn't not do it.<br></blockquote><div><br></div><div>Agreed. At Dropbox we use %(name)s in our i18n strings and the code always ends up looking ugly.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
One of the things that intrigues me about this whole idea of syntactic and<br>
compiler support is the ability to narrow down the set of substitution values<br>
available for interpolation, by parsing the source string and passing them<br>
into the interpolation call.<br>
<br>
Currently, _() is forced to expose all of locals and global to interpolation,<br>
although I guess it could also parse out the $-placeholders in the source<br>
string too[1].  Not doing this does open an information leak vector via<br>
maliciously translated strings.  If the source string were parsed and *only*<br>
those names were available for interpolation, a maliciously translated string<br>
couldn't be used to expose additional information because the keys in the<br>
interpolation dictionary would be limited.<br></blockquote><div><br></div><div>Yes, this is a real advantage of pursuing the current set of ideas further.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This mythical scope() could take arguments which would name the variables in<br>
the enclosing scopes it should export.  It would still be a PITA if used<br>
explicitly, but could work nicely if i-strings essentially boiled down to:<br>
<br>
    placeholders = source_string.extract_placeholders()<br>
    substitutions = scope(*placeholders)<br>
    translated_string = i18n.lookup(source_string)<br>
    return translated_string.safe_substitute(substitutions)<br>
<br>
That would actually be quite useful.<br></blockquote></div><br></div><div class="gmail_extra">Agreed. But whereas you are quite happy having only simple variable names in i18n templates, the feature required for the non-i18n use case really needs arbitrary expressions. If we marry the two, your i18n code will just have to yell at the programmer if they use something too complex for the translators as a substitution. So possibly PEP 501 can be rescued. But I think we need separate prefixes for the PEP 498 and PEP 501 use cases; perhaps f'{...}' and _'{...}'. (But it would not be up to the compiler to limit the substitution syntax in _'{...}')<br clear="all"></div><div class="gmail_extra"><br>-- <br><div class="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div></div>