On Apr 1, 2020, at 20:59, Steven D'Aprano <st...@pearwood.info> wrote:
> 
> 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.

I think it’s worth separating the two.

There is a legitimate desire for a “better” way to build strings than str.join. 
And a string builder type is one obvious solution, as used in many other 
languages, like Java. To be worth adding, this string builder type should be 
more discoverable than str.join, and at least as readable, and close to as 
efficient in both time and space. Ideally, it should be more readable to people 
with a visceral dislike of str.join, and be significantly better in space (by 
not retaining all of the input strings for the entire length of the building 
process) on all Python implementations, and there should also be an easy to use 
backport.

Almost none of this is true for StringIO.__iadd__, but all of it could easily 
be true for a new string.StringBuilder (using the name I think Stephen 
suggested). It’s an obvious name, that will probably be the first thing anyone 
finds in any reasonable search for how to do a string builder in Python. Once 
found, the meaning is pretty clear. And its help or docs will be useful, 
concise, and to the point instead of being all about irrelevant and confusing 
file stuff with += buried somewhere in the middle as a synonym for write. It 
can’t be easily misused (e.g., even people who know StringIO enough to suggest 
using it as a string builder mistakenly think `sb = StringIO('abc'): 
sb.write('def')` will append rather than overwrite). It can be documented to be 
roughly as fast as str.join but without retaining all of the input strings, on 
all implementations, which isn’t true for StringIO (which saves no space on 
some implementations, like CPython, and saves space at the cost of wasting a 
lot of time on others). It can have a better API—take an initial string on 
construction, give a useful repr for debugging, etc. Once there are pure-Python 
and C implementations, backporting them should be trivial—and, because it’s a 
new class rather than a change to an existing one, using the backport will be 
trivial too:

    try:
        from string import StringBuilder
    except ImportError:
        from stringbuilder import StringBuilder # pip install this

    sb = StringBuilder()
    for thing in things:
        sb += make_a_string(thing)
    s = str(sb)

And of course people who only need to support 3.10+ could just import directly 
without the backport.

This would still violate TOOWDTI. And that koan really isn’t just a joke; it’s 
a serious guideline, just not an absolute one. Adding a second way to do 
something faces an extra hurdle that has to be overcome, beyond the usual 
hurdle of conservativeness, but plenty of proposals have overcome that 
hurdle—str.format, for example, had obvious huge costs from two ways to do 
something so basic, but its benefits (especially in extensibility) were even 
huger. Here, the benefits aren’t as large, but the cost isn’t either. So it’s 
at least arguable that it’s worth doing—not because we should ignore TOOWTDI, 
but because the benefits in discoverability, readability, and maybe space 
efficiency outweigh the cost of two ways to do it.

If someone wants to propose a string builder that meets that burden (and write 
the Python and C implementations), I’d be +0.5. But StringIO.__iadd__ does not, 
which is why I’m -1 on it.

(For a third-party library, I’m not sure I’d bother with a C implementation—it 
can just check if CPython and if so use a str as its buffer… but for a builtin 
member of a stdlib module, that’s probably not acceptable.)

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

Reply via email to