On Mon, Aug 26, 2019 at 11:03:38PM -0000, [email protected] 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/[email protected]/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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/I7HPIORTO5JIQ2HZCKGIGZMOKZAKISPS/
Code of Conduct: http://python.org/psf/codeofconduct/