On Wed, Apr 01, 2020 at 09:25:46PM -0400, Kyle Stanley wrote:

> While I agree that it's sometimes okay to go outside the strict bounds of
> "only one way to do it"

The Zen of Python was invented as a joke, not holy writ, and as a series 
of koans intended to guide thought, not shut it down. Unfortunately, and 
with the greatest respect to Tim Peters, in practice that's not how it 
is used, *particularly* the "One Way" kaon, which is almost invariably 
used as a thought-terminating cliche.

1. The Zen doesn't mandate *only one way*, that is a total cannard about 
Python invented by the Perl community as a criticism.

2. Even if it did say "only one way", even a moment's glance at the 
language would show that it is not true. 

And moreover it *cannot* be true in any programming language. Given any 
task but the must basic, there will always be multiple possible 
implementations or algorithms, usually an *infinite* number of ways to 
do most things. (Not all of which will be efficient or sensible.)

3. Of all the koans in the Zen, the "One Way" koan is probably intended 
the most to be an ironic joke, not taken too seriously. Instead the 
Python community treats it as the most serious of all.

In Tim Peter's own words:

    In writing a line about "only one way to do it", I used a device (em 
    dash) for which at least two ways to do it (with spaces, without 
    spaces) are commonly used, neither of which is obvious -- and 
    deliberately picked a third way just to rub it in.

https://bugs.python.org/issue3364

Let's look at what the koan actually says:

There should be one-- and preferably only one --obvious way to do it.

Adding emphasis:

"There SHOULD BE ONE OBVIOUS WAY to do it."

with only a *preference* for one way, not a hard rule. And given that 
Tim wrote it as a joke, having the koan intentionally go against its own 
advice, I think we should treat that preference as pretty low.

So... what is "it", and what counts as "obvious"? This is where the koan 
is supposed to open our minds to new ideas, not shoot them down.

In this case, "it" can be:

1. I want to build a string as efficiently as possible.

2. I want to build a string in as easy and obvious a way as possible.

(There may be other "its", but they are the two that stand out.)

For option 1, there is one recommended way (which may or may not be the 
most efficient way -- that's a quality of implementation detail): use 
list plus join. But it's not "obvious" until you have been immersed in 
Python culture for a long time.

For option 1, Paul's proposal changes nothing. If list+join is the 
fastest and most efficient method (I shall grant this for the sake of 
the argument) then nothing need change. Keep doing what you are doing.

The koan isn't satisfied in this case, there is One Way but it isn't 
Obvious. But Paul's proposal is not about fixing that.

-----

For option 2, "it" cares more about readable, self-documenting code 
which is clear and ovious to more than just Pythonistas who have been 
immersed in the language for years. The beauty of Python is that it 
ought to be readable by everyone, including scientists and hobbists who 
use the language from time to time, students, sys admins, and coders 
from other languages.

Ask a beginner, or someone who has immigrated from another language, 
what the obvious way to build a string is, and very few of them will say 
"build a list, then call a string method to join the list".

Some of them might guess that they need to build a list, then call a 
*list* method to build a string: `list.join('')`. Why Python doesn't do 
that is even a FAQ.

Beginners will probably say "add the strings together". People coming 
from other OOP languages will probably say "Use a String Builder", and 
possibly even stumble across StringIO as the closest thing to a builder. 
It's a bit odd that you have to call "write", but it builds a string out 
of substrings.

(Later, in another post, I will give evidence that StringIO is already 
used as a string builder, and has been for a long time.)

A significant sector of the community know the list+join idiom, but 
dislike it so strongly that they are willing to give up some efficiency 
to avoid it.

Whatever the cause, there is a significant segment of the Python 
community who either don't know, don't care about, or actively dislike, 
the list+join idiom. For them, it is not Obvious and never will be, the 
Obvious Way is to concatenate strings into a String Builder or a bare 
string.

This segment, the people who use string concatenation and either don't 
know better, don't care to change, or actively refuse to change, is the 
focus of this proposal. For this segment, the One Obvious Way is to 
concatenate strings using `+=`, and they aren't going to change for the 
sake of other interpreters.

And that's a problem for other interpreters. Hence Paul's RFC.


[...]
> Regarding the proposal in general though, I actually like the main idea of
> having "StringBuffer/StringBuilder"-like behavior, *assuming* it provides
> substantial benefits to alternative Python implementations compared to
> ``""join()``. As someone who regularly uses other languages with something
> similar, I find the syntax to be appealing, but not strong enough on its
> own to justify a stdlib version (mainly since a wrapper would be very
> trivial to implement).

Surely the fact that the wrapper is "trivial" should count as a point in 
its favour, not against it?

The greater the burden of an enhancement request, the greater the 
benefit it must give to justify it. If your enhancement requires a 
complete overhall of the entire language and interpreter and will 
obsolete vast swathes of documentation, the benefit has to be very 
compelling to justify it.

But if your enhancement requires an extra dozen lines of C code, one or 
two tests, and an extra couple of lines of documentation, the benefit 
can be correspondingly smaller in order for the cost:benefit ratio to 
come up in its favour.

The cost here is tiny. This thread alone has probably exceeded by a 
factor of 100 the cost of implementing the change. The benefit to 
CPython is probably small, but to the broader Python ecosystem (Paul 
mentioned nine other interpreters, I can think of at least two actively 
maintained ones that he missed) it is rather larger.


> But, I'm against the idea of adding this to the existing StringIO class,
> largely for the reasons cited above, of it being outside of the scope of
> its intended use case. There's also a significant discoverability factor to
> consider. Based on the name and its use case in existing versions of
> Python, I don't think a substantial number of users will even consider
> using it for the purpose of building strings. As it stands, the only people
> who could end up benefiting from it would be the alternative
> implementations and their users, assuming they spend time *actively
> searching* for a way to build strings with reduced memory usage. So I would
> greatly prefer to see it as a separate class with a more informative name,
> even if it ends up being effectively implemented as a subset of StringIO
> with much of the same logic.

As I mentioned above, in another post to follow I will demonstrate that 
people already do know and use StringIO for concatenation.

Nevertheless, you do make a good point. It may be that StringIO is not 
the right place for this. That can be debated without dismissing the 
entire idea.



-- 
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/IK2HAQUQOT26ZUC6IAZV3W75P6EBNVTI/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to