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/

Reply via email to