
On Mon, 3 May 2021 at 04:00, David Álvarez Lombardi <alvarezdqal@gmail.com> wrote:
This is the mindset that I had. I understand there are other ways to do what I am asking. (I provided one in my initial post.) I am saying it relies on what I believe to be a notoriously unintuitive method (str.join) and an even more unintuitive way of calling it ("".join).
I think this is something of an exaggeration. It's "notoriously difficult" (;-)) for an expert to appreciate what looks difficult to a newcomer, but I'd argue that while ''.join() is non-obvious at first, it's something you learn once and then remember. If it's really awkward for you, you can write `concat = ''.join` and use that (but I'd recommend against it, as it makes getting used to the idiom *other* people use that much harder).
Here are 73 of them that I found by grepping through Lib.
Thank you. I only spot-checked one or two, but I assume from this list that your argument is simply that *all* occurrences of ''.join(something) can be replaced by c"something". Which suggests a couple of points: * If it doesn't add anything *more* than an alternative spelling for ''.join, is it worth it? * Is the fact that it's a quoted string construct going to add problematic edge cases? You can't use " inside c"..." without backslash-quoting it. That seems like it could be a problem, although I'll admit I can't come up with an example that doesn't feel contrived at the moment. In particular, is the fact that within c"..." you're writing a comprehension but you're not allowed to use unescaped " symbols, more awkward than using ''.join was originally?
To me, the chosen syntax is problematic. The idea of introducing structural logic by using “” seems likely to cause confusion. Across all languages I use, quotes are generally and almost always used to introduce constant values. Sometimes, maybe, there are macro related things that may use quoting, but as a developer, if I see quotes, I’m thinking: the runtime will treat this as a constant.
I think this is an over-simplification of the quotations syntax. Python has several prefix characters that you have to look out for when you see quotes, namely the following: r, u, f, fr, rf, b, br, rb. Not only can these change the construction syntax, but they can even construct an object of a completely different type (bytes).
On the contrary, I think you're missing the point here. When I, as a programmer, see "..." (with any form of prefix) I think "that's a constant". That's common for all quoting. I'd argue that even f-strings are very careful to avoid disrupting this intuition any more than necessary - yes, {...} within an f-string is executable code, but the non-constant part is delimited and it's conventionally limited to simple expressions. Conversely, it's basically impossible to view your c-strings as "mostly a constant value". Also, how would c-strings be handled in conjunction with other string forms? Existing string types can be concatenated by putting them adjacent to each other:
a="hello" f"{a}, " r"world" 'hello, world'
How would c-strings work? As code, I might want to format a generator over multiple lines. How would c-strings work with that? ( c"val.strip().upper() " c"for val in file " c"if val != '' " # Skip empty lines c"and not val.startswith(chr(34))" # And lines commented with " - chr(34) is ", but we can't use " directly without a backslash ) That doesn't feel readable to me. I could use a triple-quoted c-string, but then I have an indentation problem. Also, with triple quoting I couldn't include those comments (or could I??? You haven't said whether comments are valid *within* c-strings. But I assume not - the syntax would be a nightmare otherwise).
Second, f-strings do not restrict the normal usage of strings for freeform text content (apart from making the curly brace characters special).
Not to nit-pick too much, but the following is a valid string but not a valid f-string.
s = f"This is a valid string but invalid f-string {}" File "<stdin>", line 1 s = f"This is a valid string but invalid f-string {}" ^ SyntaxError: f-string: empty expression not allowed
That comes under the heading of making curly braces special...
Your proposal is focusing on strings as iterables and drawing a parallel with other kinds of iterables for which we have comprehensions. But strings aren't like other iterables because they're primarily vessels for freeform text content, not structured data.
I view this as the strongest opposition to the idea in the whole thread, but I think that seal was broken with f-strings and the {}-syntax. The proposed syntax is different from those features only in *degree* (of deviation from strict char-arrays) not in *type*. But I also recognize that the delimiters {} go a long way in helping to mentally compartmentalize chars from python code.
That's a very explicit "slippery slope" argument - "now that f-strings stopped quotes meaning constant, we can do anything we like" - and like most such arguments, it's a massive over-generalisation. f-strings were debated very carefully, and a lot of effort was put into the question of whether it broke the "literal string" intuition too much. The conclusion was that it didn't, *for that specific case*. But there's no reason to assume that the same arguments apply for other uses (and indeed, the decision was close enough that there's very good reasons to assume those arguments *won't* apply in general).
I definitely see the drawbacks of the originally-proposed syntax, but I think it would be beneficial to the conversation for commenters to recognize that python strings are not nearly as pure as some of the objections make them out to be. I would be happy to hear the objection that my syntax strays *too* far, but many of the passed-around examples attest to the fact that when users see quotes, they are often already in "code-evaluation" mode (eg. f"[{','.join('0123')}]" ).
OK. I'll object in those terms. I think your syntax proposal strays *way* too far. And I don't believe the example you gave is a good use of f-strings - I don't recall the context, but if it was from real code (rather than being a constructed example to make a point) I'd strongly insist that it be rewritten for better readability.
I think that a comment left by steve was particularly helpful.
If we were re-doing Python from scratch, there's a good chance that we would limit ourselves to a single comprehension syntax, namely generators:
list(expression for x in items if cond) set(expression for x in items if cond) dict((key, value) for x in items if cond)
rather than have dedicated syntax for those three cases.
Would readers see any merit in a syntax like the following?
dirty = "f8sjGe7" clean = str(char for char in dirty if char in string.ascii_letters) clean 'fsjGe'
Or would it stray too far from the behavior of the str() constructor in general?
Would you object to using a different function rather than re-using the str constructor? How about "concat"? Or maybe ''.join? OK, so that was a little facetious, but hopefully you get my point, that you've now reached the point where you're in effect saying that the only thing you really want to change is the name of the ''.join function.
As of now, the behavior is the following.
dirty = "f8sjGe7" clean = str(char for char in dirty if char in string.ascii_letters) clean '<generator object <genexpr> at 0x7f10fc917660>'
And that's why reusing str isn't going to be an option. It's a backward compatibility issue. It's not so much that anyone is relying on str() returning that particular value, but they *do* rely on it returning a (semi-)readable representation of the passed in value, and not executing it if it's a generator.
I don't intend to reinvent strings, I only mean to leverage an already existing means of signifying modified string construction syntax (prefixes) to align str construction syntax with the comprehensions available for the other most common builtin iterables, avoid the notoriously unintuitive "".join syntax, and improve readability.
The fact that you're getting responses suggesting you do want to "reinvent strings" implies that your proposed syntax is being understood in a way that wasn't your intent. That in itself is a strong indicator that the syntax isn't nearly as intuitive as you'd hoped (or as a language construct for Python typically needs to be to fit in with Python's "easily readable" style).
Please continue to send your thoughts! I really appreciate it!
I hope the above was of use. Overall, I'm a strong -1 on this proposal, I'm afraid. Paul