
PEP 0501 – Translation ready string interpolation - Sami_Lehtinen
https://www.python.org/dev/peps/pep-0501/
======
svieira
I like the general thrust of PEP 498 (`f""` is explicit, unlike Ruby or Bash's
magic `"` vs. `'`).

That said, I think it would be much improved if it went the way of Scala and
JavaScript (2015+) and made `r`, `u`, `b`, and `f` all interpolation
providers. That way libraries could provide interpolators without having to
extend the language to create a new one.

For example, in Scala or JavaScript, you can create a string context /
template tag for composing JSON strings, resulting in a nice syntax like this
(scala-like):

    
    
        json"""{
          "my": $data,
          "anArray": $someArray
        }"""
    

The `data` and `someArray` values serialized to JSON by the `json`
interpolation provider.

At that point, internationalization is just creating your own interpolation
provider and importing it as `i`, which is far less machinery than this PEP
requires.

~~~
dragonwriter
> (`f""` is explicit, unlike Ruby or Bash's magic `"` vs. `'`)

Both are equally explicit, though f"" is perhaps marginally more clear because
it is somewhat mnemonic.

------
imakesnowflakes
Reddit discussion

[https://www.reddit.com/r/Python/comments/3gfaji/pep_501_tran...](https://www.reddit.com/r/Python/comments/3gfaji/pep_501_translation_ready_string_interpolation/)

I think this and pep 498 are a pretty horrible proposals and does not fit well
with the rest of the language and it's spirit.

1\. Decrements readability. When variables are hidden inside strings, you need
to check for presence of a variable in two contexts. In the code and inside
the strings. With format and % functions, you will be able to spot the
variable in the argument list, which is part of the code itself.

2\. Security concerns regarding automatic evaluation of expressions inside the
strings.

Also, why was format and % made in such a way as to require an explicit list
of variables? What was the reasoning behind it? Is that reason no longer
relevant?

~~~
masida
I agree. For me the automatic "pulling" of local variables from the context
feels like "magic", and I think that's an undesirable property for a
programming language. Of course, PEP498 has the same issue.

~~~
kerkeslager
> For me the automatic "pulling" of local variables from the context feels
> like "magic", and I think that's an undesirable property for a programming
> language.

Sounds like "Explicit is better than implicit" from the Tao of Python.

------
kerkeslager
I'm currently working on a heavily internationalized website written in Python
3[1] and as such I've had opportunity to work with a few ways of
internationalizing content. My thoughts:

1\. Internationalization is, as far as I know, an unsolved problem. This
solution doesn't stand out as obviously better than the alternatives. Unsolved
problems don't belong at the language level. I'd rather wait until a real
solution to this problem is discovered.

2\. What happened to explicit is better than implicit? Isn't that a core value
of Python? Overriding implementations of builtin functions is all too magical,
allowing spooky action at a distance. I'm extremely skeptical of solutions
that don't allow me to grep my code for where a function is implemented.
`gettext`, at least is clearly calling a function.

[1] [http://globalcitizen.org](http://globalcitizen.org)

------
byuu
The idea that a translation string can execute Python code via ${expression}
is really quite scary. Imagine a user downloading a third-party localization
file that ends up being malicious.

Overall, I see there being two major styles for building strings. Since I use
C++, I can't do literal interpolation, but I can get close with variadic
templates. I hope you guys won't me talking about a statically typed language
here, but it should be on topic to string interpolation at least.

    
    
        //interpolation
        print("My name is ", name, " and next year, I will be ", age + 1, " years old.\n");
        
        //arguments
        print("My name is {0}, and next year, I will be {1} years old.\n", name, age + 1);
        
        //arguments with hinting (:label is ignored)
        print("My name is {0:name}, and next year, I will be {1:age} years old."\n", fetch(), *values + 1);
        
        print(hex(size, 4), " KiB");  //interpolation formatting
        print("{0,4x} KiB", size);    //argument formatting (more covenient, but more cryptic and limited)
        
        //without the print component:
        string s{"My name is: ", name, "\n"};  //interpolation
        string s{"My name is: {0}\n", name};   //arguments
    

The latter is certainly vastly superior for localization. Because in another
language, it may be more grammatically correct to reverse the parameters, eg:
"来年の歳は{1}と名前は{0}"; which is something C printf doesn't support, shy of
unofficial extensions for argument reordering.

But I find that as the string gets longer and longer, the former is much more
readable. (You'll have to imagine the syntax highlighting, which helps a lot.)
Eg when you have 17 arguments, it can be annoying to count to find the 11th
parameter, whereas with interpolation, it's right there where it's used.

Ultimately, I decided on the former being the default, and added a format
class for the latter, which is also really handy for building your argument
lists somewhere else. Plus the default won't clobber your escape characters
(in my case, braces.)

    
    
        //inline format
        print("I am {0}, and I'm {1} years old.\n", format{name, age});
        
        //external format
        format f;
        f.append(fetch());      //person's age
        f.append(*values + 1);  //person's name
        ...  //you could fetch the string from a translation table below, too
        print("I am {0}, and I'm almost {1} years old.\n", f);
    

Whenever string::append(format) is invoked, it will use all of the values
inside the format array to parse {#} entries in the string. Of course, it's
also safe and will simply skip over a reference to {2} in a format array with
only one value.

Curious to hear others' opinions on the above, and any suggestions for
improvement.

