-
-
Notifications
You must be signed in to change notification settings - Fork 300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow escaping newlines in double-quoted strings to remove the EOL char(s) #1656
Comments
Note that Elvish does not support interpolating variables in double-quoted strings the way POSIX shells do; e.g., |
Some random thoughts: Isn't there a (much) greater need for removing the initial newline than the final one? I imagine one often would want the final newline in practice. I think any syntax that clashes with present syntax, as the python style would, is a really bad idea. Instead, use some syntax that is not allowed today. For example, the line continuation character This might make some sense because |
A stray thought hit me as I was going to bed. Here is a solution in today's elvish:
Or you could use In light of this, removal of initial common white space is a stronger argument for new syntax. (The |
There are a couple of reasons. First, symmetry. Second, the
Okay, but your proposal to special-case a
And if we do decide to use |
Very quick folluwup, as I am short on time: I think you misread my proposal – eh, stray thought. I did not intend to suggest giving
That is currently illegal syntax, so this is not a breaking change. And about the final newline: My thinking was, the |
Ugh! No. Not least because it only elides the first newline and does not provide a mechanism for eliding newlines, for readability (to keep the literal lines a reasonable length), inside triple double-quoted strings. For example:
I am confused if we are in agreement or not vis-a-vis eliding any final newline in a triple-quoted string. You wrote "the normal expectation would be for a multiline string to end with a newline." Which implies you expect a multiline, triple-quoted, string to always end in a newline. Which makes it impossible to use
If you really want a leading newline in that case you simply add an empty line:
|
I am responding a bit out of order …
That is probably because I haven't made up my mind about it, so I am not advocating very strongly for it. In fact, I haven't made up my mind about any aspect of my proposal, except I think it's worth investigating and dismissing out of hand. So, with that in mind, let's look at the question of eliding the final newline. With my proposed syntax, just put the terminating quote at the end of the last line instead of at the beginning of the next line. Perhaps we are talking past each other here? Perhaps we have different reasons for wanting the feature in the first place? After all, the good old single quote strings can be multiline strings already. There are two problems with them that I can see:
And that's it, is it not? From this perspective, the final newline might be less important, though I concede that always putting the ending quote(s) on a separate line will help to make the string stand out better in the source code, and that is a good thing. And if we do that, then yes, eliding the final newline is a good idea. (Although the trick of adding Whether we go for Sorry for being long-winded, but since this is not so much technical as human oriented, I couldn't make it any shorter. |
I've decided that there should not be new literal string syntax. Instead, there should be a new |
The problem with a Re the syntax, triple quotes would be an obvious choice, but - to recap the conversation a bit - But there are other choices. Elvish currently reserves |
Re the original feature request in the title: I don't see a use case listed other than removing the first newline in a multi-line literal, but multi-line literals are better served by something that also removes initial whitespaces. Unless there are more use cases I'm inclined to reject this feature. |
The rationale was to remove the initial newline and elide leading whitespace like the POSIX "heredoc" mechanism does. I see in hindsight my example didn't make that clear. Furthermore, the POSIX "heredoc" mechanism only removes leading tabs, not spaces or a mixture of the two, which I consider an unnecessary and unwanted limitation.
I don't grok that comment (but then I haven't yet read your |
I looked at your That your implementation panics if any subsequent line does not have the same prefix explains your comment that "the problem with a dedent command is that it's not possible for the parser to check the syntax." However, even if the parser were to validate that a literal string argument to a I googled a bit and this ECMAscript "String Dedent proposal" description best encapsulates the behavior I expect from an Elvish
It is possible, even likely, the implementation I included in my pull-request did not conform to that behavior. But I strongly believe the behavior described above is what we want, at least as the default behavior, and that the behavior of your |
Note that by "first line" I mean the first line after ignoring a leading newline. |
The reason ... dedent(`
foo
bar
`) This looks like two lines with the same indentation, containing
Both are not ideal. Granted, one could configure their editor to show markers for spaces and tabs to make this problem easier to spot, but even with such configurations, when the text consists of many lines, using the wrong indentation in one of those lines will mess up the entire literal. The solution is using a fixed line to establish the indentation, and require that all other lines start with that indentation. My But there is a solution to that too: use the last line to establish the reference indentation. This is what Swift's multiline string literal uses. On first look it seems to have just transferred the requirement to the last line, but Swift solves this by requiring the closing delimiter to appear on its own and eliding the trailing newline. Swift's doc has a few examples that should make this clear. Swift's syntax also solves another problem: it allows writing strings where each line is indented by the same amount. In fact, Swift's syntax is the only one that doesn't place any restriction on what the text content can be.
Now, removing common indentation does have the advantage that it admits all input, and is a sensible choice when it has to be implemented as a function rather than new syntax. But for a new syntax it'd be a shame to not follow Swift's lead. It's very well thought to avoid the problems of other syntax choices. The only drawback I see is that the eliding of the trailing newline is slightly unusual, but it's not that hard to get used to. Another reason for wanting a new string literal syntax is to allow writing text that has a lot of quotes themselves. This is more important than eliding indentation (which is purely cosmetic). I've already rejected triple single quotes (because it does something useful today) and triple double quotes (because I don't like the asymmetry if you can do var x = <<<"
foo\x00
bar
">>>
# equivalent to:
var x = "foo\x00
bar"
var y = <<<'
foo\x00
bar
'>>>
# equivalent to:
var y = 'foo\x00
bar'
var z = <<<<'
var x = <<<'
foo
'>>>
'>>>>
# equivalent to:
var z = "var x = <<<'
foo
'>>>" |
I agree that is the best approach for dedenting string literals. However, that precludes supporting dedenting arbitrary strings; e.g., via variable interpolation to a hypothetical
This is a case where my experience with other languages (e.g., POSIX 1003.1 and Python) unduly affected my thinking. I can't recall a single instance where I have used, or seen, the Python |
There was a question in the chat channels about the Elvish equivalent for a POSIX here-doc illustrated by this example:
AFAIK, the only straightforward equivalent is this:
Or this:
If double-quoted strings allowed backslash to precede the EOL char(s) then this would be valid:
Alternatively, a triple-quoted string would be aesthetically pleasing and arguably easier to use:
Here the first and last EOL char(s) are elided by the triple-quoting mechanism. This, however, is not backwards compatible given the existing rule for interpreting single-quotes inside a single-quoted string. There is a similar problem for double-quoted strings. But, if we're willing to special-case triple quotes at the start and end of a line (when the sequence is otherwise a token with no adjacent chars other than EOL), then this is unlikely to break any existing code. It also allows us to introduce an additional filtering rule that removes leading whitespace common to all lines. For example:
Eliding EOL char(s) by prefacing them with a backslash in a double-quoted string is backward compatible and should be straightforward to implement. I can't see any downsides to supporting it and believe it should be implemented. I am ambivalent about the triple-quoted string idea but include it here to see what others think about the idea and whether it sparks any other proposals for making it easier, and clearer, to implement the equivalent of a POSIX here-doc in Elvish. I am also opposed to introducing the POSIX here-doc (
cat <<WORD\n...\nWORD
) syntax (even if its quirks are avoided) because I don't think it adds enough value relative toecho | cat
(orprint | cat
) to justify the feature.See also issue #1261.
The text was updated successfully, but these errors were encountered: