On 2020-06-17 7:44 a.m., Stephen J. Turnbull wrote:
Soni L. writes:

 > Explicit is better than implicit.
 > 
 > and \z is more explicit than #cont

It's not more explicit.  Line continuation in a string literal is
perfectly explicit and easy to explain *exactly*: "omit the '\' and
the following newline from the string being constructed".  You could
argue that '\z' is more easily visible ("readable" if you like), but
not that it's more explicit.

The simplest form of '\z' is "almost easy" to explain exactly ("omit
the following newline and all leading whitespace on the next line").
Complication enters when we ask, "but what happens if the character
following '\z' is not a newline?"

But more generally, string dedenting is hard to explain with much
precision, let alone exactly, except in (pseudo)code.  '\z' would be
even more complicated than textwrap.dedent, because it would apply
line by line.  Would the indentation that is stripped be string-wide
(so that '\z' could work like RFC 822 folding with the intended
whitespace at the *left* margin, where it's easy to see), or would
each '\z' just strip all the indentation on the next line?  Maybe '\z'
should replace all the surrounding whitespace with a single space?

Read the Lua docs. It makes it very simple:

"The escape sequence '\z' skips the following span of white-space characters, including line breaks; it is particularly useful to break and indent a long literal string into multiple lines without adding the newlines and spaces into the string contents."

Note that, in Lua, you can "break" the \z by inserting an \x20. This is because it only cares about literal whitespace.

> "foo\z   \x20bar"
foo bar

which is particularly useful for inserting indents into the string while also using \z. Oh, also, it matches zero-or-more, altho I guess an error would also be compliant with what's written in the manual. (And yes, Lua does leave stuff like this "undefined" all the time. We might want to explicitly specify "[...] span of zero-or-more [...]" tho.)

This also gives us two ways of doing indented strings (in Lua):

local ugly = "foo\n    \z
                  bar\n    \z
                  baz"
local nicer = "foo\n\z
               \x20   bar\n\z
               \x20   baz"

Obviously textwrap.dedent is nicer but again I don't propose \z for doing this, but rather for breaking up too long strings into multiple lines. The only point is to break up too long strings into multiple lines without accidentally turning them into (part of) a tuple. Which is why I put that #cont there. Also, that example with #cont? It's inside a tuple. Someone looking at it would see the tuple and the newline and the "missing" comma and would put a comma there so I need to put #cont there and having \z would be a better way to solve that.


I kinda like the string-wide idea, but

    s = textwrap.dedent("""\
    This\
     is\
     a\
     silly\
     example\
     of\
     a\
     dedented\
     and\
     folded\
     string.\
    """)
    assert s == "This is a silly example of a dedented and unfolded string."

works for me, specifically in real examples where *occasionally* for
some reason I want to fold a long line.  That is, although the
trailing '\' at the right margin is not so easy to see, the extra
space at the left margin of the next line is easy to see (at least
with a reasonable font).

Of course,

    s = "This"
        " is"
        " a"
        ...

works even better when what you want is an unfolded one-line string.

Steve