On Mon, Aug 26, 2019 at 11:03:38PM -0000, stpa...@gmail.com wrote: > In Python strings are allowed to have a number of special prefixes: > > b'', r'', u'', f'' > + their combinations. > > The proposal is to allow arbitrary (or letter-only) user-defined prefixes as > well. > Essentially, a string prefix would serve as a decorator for a string, > allowing the > user to impose a special semantics of their choosing. > > There are quite a few situations where this can be used: > - Fraction literals: `frac'123/4567'`
Current string prefixes are allowed in combinations. Does the same apply to your custom prefixes? If yes, then they are ambiguous: how could the reader tell whether the string prefix frac'...' is a f- r- a- c-string combination, a fra- c-string combination, a fr- ac-string combination, or a f- rac- string combination? If no, then it will confuse and frustrate users who wonder why they can combine built-in prefixes like fr'...' but not their own prefixes. What kind of object is a frac-string? You might think it is obvious that it is a "frac" (Fraction? Something else?) but how about a czt-string? As a reader, at least I know that czt('...') is a function call that could return anything at all. That is standard across hundreds of programming languages. But as a string prefix, it looks like a kind of string, but could be anything at all. Imagine trying to reason about Python syntax: 1. u'...' is a unicode string, evaluating to a str. 2. r'...' is a raw string, evaluating to a str. 3. f'...' is a f-string, evaluating to a str. 4. b'...' is a byte-string, evaluating to a bytes object, which is not a str object but is still conceptually a kind of string. 5. Therefore z'...' is what kind of string, evaluating to what kind of object? Things that look similar should be similar. This string prefix idea means that things that look similar can be radically different. It looks like a string, but may not be anything like a string. The same applies to function call syntax, of course, but as I mentioned above, function call syntax is standard across hundreds of languages and readers don't expect that the result of an arbitrary function call is necessarily the same as its first argument(s). We don't expect that foo('abcde') will return a string, even if we're a little unclear about what foo() actually does. u- (unicode) strings, r- (raw) strings, and even b- (byte) strings are all kinds of *string*. We know just by looking at them that they evaluate to a str or bytes object. Even f-strings, which is syntax for executable code, at least is guaranteed to evaluate to a str object. But these arbitrary string prefixes could return anything. > This proposal has been already discussed before, in 2013: > > https://mail.python.org/archives/list/python-ideas@python.org/thread/M3OLUURUGORLUEGOJHFWEAQQXDMDYXLA/ > > The opinions were divided whether this is a useful addition. The opponents > mainly argued that as this only "saves a couple of keystrokes", there is no > need to overcomplicate the language. Indeed. czt'...' saves only two characters from czt('...'). > It seems to me that now, 6 years later, > that argument can be dismissed by the fact that we had, in fact, added new > prefix "f" to the language. I don't see how that follows. The existence of one new prefix adds *this* much new complexity: [holds forefinger and thumb about a millimeter apart] for significant gains. Trying to write your own f-string equivalent function would be quite difficult, but being in the language not only is it faster and more efficient than a function call, but it needs to be only written once. But adding a new way of writing single-argument function calls with a string argument: czt'...' is equivalent to czt('...') adds *this* much complexity to the language: [holds forefingers of each hand about shoulder-width apart] for rather insignificant gains, the saving of two parentheses. You still have to write the czt() function, it will have to parse the string itself, you will have no support from the compiler, and anyone needing this czt() will either have to re-invent the wheel or hope that somebody publishes it on PyPI with a suitable licence. > Note how the "format strings" would fall squarely > within this framework if they were not added by now. > > In addition, I believe that "saving a few keystroked" is a worthy goal if it > adds > considerable clarity to the expression. Readability counts. Compare: > > v"1.13.0a" > v("1.13.0a") What's v() do? Verbose string? > To me, the former expression is far easier to read. Parentheses, especially as > they become deeply nested, are not easy on the eyes. But, even more > importantly, > the first expression much better conveys the *intent* of a version string. Oh, you intended a version string did you? If only you had written ``version`` instead of ``v`` I might not have guessed wrong. What were you saying about preferring readability and clarity over brevity? *semi-wink* I'm only half joking here. Of course I could guess that '1.13.0a' looks like a version string. But I genuinely expected v-string to mean "verbose", not version, and could only guess otherwise because I know what version strings look like. In other words, I got *all* of the meaning from the string part, not the prefix. The prefix on its own, I would have guessed completely wrong. This goes against your claim that "the string has no meaning of its own". Of course it has meaning on its own. It looks like a version string, which is the only way I could predict that v'...' stands for version-string rather than verbose-string. What if we didn't recognise the semantics of the string part? v'cal-{a}-%.5f-^H/7:d{b}s' What's this v-string mean, what does it do, how do I parse the string part of it? I think that one of the weaknesses of this proposal is that you are assuming that the meanings of these prefixes are as obvious to everyone else as they are to you. They aren't. > It has a feeling of an immutable object. How are we supposed to know that v-strings return an immutable object? Let's suppose you come across l'abc' in somebody's code base. What's an l-string? Does it still look immutable to you? What if I told you that l-string stands for "list-string" and it returns a mutable list? > In the second case the string is passed to the constructor, but the > string has no meaning of its own. As such, the second expression feels > artificial. Consider this: if the feature already existed, how *would* > you prefer to write your code? If I wanted to parse a string and return a Version object, I would write it as Version('1.13.0a'). If your v-string prefix does something other than that, I cannot comment, as I have no idea what your v-string prefix would do or how it would differ from the regular string '1.13.0a'. -- Steven _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/I7HPIORTO5JIQ2HZCKGIGZMOKZAKISPS/ Code of Conduct: http://python.org/psf/codeofconduct/