Oops, my apologies for misspelling your name.  It was a typo.

> On Apr 13, 2017, at 8:35 AM, Ricardo Parada via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> Adriam
> 
> Take a look at Brent's revised proposal.I personally thin it is perfect.  
> Take a look:
> 
> https://github.com/johnno1962a/swift-evolution/blob/master/proposals/0168-multi-line-string-literals.md
>  
> <https://github.com/johnno1962a/swift-evolution/blob/master/proposals/0168-multi-line-string-literals.md>
> 
> 
> Regarding what you are proposing:
> 
> Trailing newline 
> 
> We need consensus on whether the trailing newline on the last line should be 
> included.  You are proposing it should not be included which will add an 
> empty line to Brent's xml concatenation example. The example looks better 
> when the trailing newline is included. 
> 
> In the more rare case where the newline is not desired on the last line then 
> you can just include the backslash at the end. See Brent's revised proposal: 
> https://github.com/johnno1962a/swift-evolution/blob/master/proposals/0168-multi-line-string-literals.md
>  
> <https://github.com/johnno1962a/swift-evolution/blob/master/proposals/0168-multi-line-string-literals.md>
> 
> Trailing whitespace 
> 
> You also propose to remove trailing white space in each line unless the 
> whitespace is followed by a backslash.   For example:
> let str_2 = """↵  
> foo··↵
> """
> The two trailing whitespaces after foo would get removed according to what 
> you are proposing. I don't like this rule. I think we are better off with 
> leaving it alone and to the tools as Brent suggested. 
> 
> Regards,
> Ricardo Parada
> 
> 
> 
> 
> On Apr 13, 2017, at 5:28 AM, Adrian Zubarev via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> Now that I had some sleep I actually revise my opinion about the last line. 
>> I took a few hours to sum my thoughts together in a gist, here is a 
>> formatted version of it: 
>> https://gist.github.com/DevAndArtist/dae76d4e3d4e49b1fab22ef7e86a87a9 
>> <https://gist.github.com/DevAndArtist/dae76d4e3d4e49b1fab22ef7e86a87a9>
>> Simple ‘multi-line string literal’ model
>> 
>> Core features:
>> 
>> Omitting of (most) backslashes for ".
>> Altering the string with implicit new line injection at the end of the line.
>> Consequences of #1:
>> 
>> To omit escaping the quote character, the delimiter characters for the 
>> multi-line string literal will be tripled quotes """, also similar to other 
>> programming languages.
>> 
>> When a standard string literal contains at least 5 quotes, then the usage of 
>> a multi-line string literal will be shorter.
>> 
>> "<a href=\"\(url)\" id=\"link\(i)\" class=\"link\">"    // With escapes
>> """<a href="\(url)" id="link\(i)" class="link">"""      // With tripled 
>> literals
>> Consequences of #2:
>> 
>> To fully support this feature, we need to compromise the design for 
>> simplicity and intuitivity.
>> 
>> This feature needs precision for leading and trailing spaces.
>> Alternatively one would need a way to disable new line injection to also 
>> support code formatting.
>> Two ways of writing a multi-line string literal:
>> 
>> Single line version """abc""" is trivial and already was shown above.
>> 
>> The multi-line version comes with a few compromises for simplicity of rules:
>> 
>> """   // DS (delimiter start)
>> foo   // s0
>> foo   // s1
>> foo   // s2
>> """   // DE (delimiter end)
>> The string content is always written between the lines DS and DE (delimiter 
>> lines). 
>> 
>> To not to go the continuation quotes path, the left (or leading) precision 
>> is handled by the closing delimiter (1. compromise). The closing delimiter 
>> is also responsible for the indent algorithm, which will calculate the 
>> stripping prefix in line DE and apply stripping to lines s0 to sn.
>> 
>> Right (or trailing) precision of each line from s0 to sn (notice n equals 2 
>> in the example above) is handled by a backslash character (2. compromise).
>> 
>> The right precision comes at a price of losing the implicit new line 
>> injection, however this was also a requested feature (3. compromise). That 
>> means that the backslash serves two jobs simultaneously.
>> 
>> New line injection happens only on lines s0 to s(n - 1) (4. and last 
>> compromise of the design). The last line sn (or s2 above) does not inject a 
>> new line into the final string. This implies that in this line a backslash 
>> character handles only right precision, or one could say it’s reduced to one 
>> functionality.
>> 
>> Important:
>> 
>> Because whitespace is important to these examples, it is explicitly 
>> indicated: · is a space, ⇥ is a tab, and ↵ is a newline.
>> 
>> Leading/trailing precision and indent (1. and 2. compromise):
>> 
>> // Nothing to strip in this example (no ident).
>> let str_1 = """↵  
>> foo↵
>> """
>> 
>> // No right precision (no backslash) -> whitespaces will be stripped.
>> let str_2 = """↵  
>> foo··↵
>> """
>> 
>> // Same as `str_2`
>> let str_3 = """↵  
>> foo····↵
>> """
>> 
>> // Line `DE` of the closing delimiter calculates the indent prefix  
>> // `··` and strips it from `s0` (left precision).
>> let str_4 = """↵  
>> ··foo↵
>> ··"""
>> 
>> // Line `DE` of the closing delimiter calculates the indent prefix  
>> // `····` and strips it from `s0` (left precision).
>> // No right precision (no backslash) -> whitespaces will be stripped.
>> let str_5 = """↵  
>> ····foo··↵
>> ····"""
>> 
>> // Line `DE` of the closing delimiter calculates the indent prefix  
>> // `⇥ ⇥ ` and strips it from `s0` (left precision).
>> // Right precision is applied (backslash). In this case the literal
>> // contains only a single line of content, which happens to be   
>> // also the last line before `DE` -> backslash only serves precision.
>> let str_6 = """↵  
>> ⇥ ⇥ foo\↵
>> ⇥ ⇥ """
>> 
>> // Line `DE` of the closing delimiter calculates the indent prefix  
>> // `·⇥ ·⇥ ` and strips it from `s0` (left precision).
>> // No right precision (no backslash) -> whitespaces will be stripped.
>> let str_7 = """↵  
>> ·⇥ ·⇥ foo··↵
>> ·⇥ ·⇥ """
>> 
>> let string_1 = "foo"
>> 
>> str_1 == string_1   // => true
>> str_2 == string_1   // => true
>> str_3 == string_1   // => true
>> str_4 == string_1   // => true
>> str_5 == string_1   // => true
>> str_6 == string_1   // => true
>> str_7 == string_1   // => true
>> A false multi-line string literal, which compiles but emits a warning and 
>> proves a fix-it:
>> 
>> let str_8 = """↵  
>> ··foo↵
>> ····"""
>> 
>> str_8 == string_1   // => true
>> warning: missing indentation in multi-line string literal
>>   ··foo!
>>     ^  
>>   Fix-it: Insert "··"
>> The stripping algorithm calculates the prefix indent from the closing 
>> delimiter line DE and tries to strip it in lines s0 to sn if possible, 
>> otherwise each line, which could not be handled correctly will emit an 
>> individual warning and a fix-it.
>> 
>> The stripping algorithm removes every whitespace on the end of each line 
>> from s0 to sn iff there is no right precision, annotated through a backslash 
>> like ··foo··\↵. This behavior is essential and aligns well with the 
>> precision behavior of a standard string literal " ", otherwise a multi-line 
>> string literal like
>> 
>> """
>> foo
>> """
>> can contain 3 characters or 10 characters or even 1000 characters, but the 
>> developer couldn’t tell or even approximately guess.
>> 
>> The correct way of fixing this, as already mentioned above, is by striping 
>> all white spaces after the last non-space character of the line, unless the 
>> right precision is explicitly annotated with a backslash.
>> 
>> """
>> foo   \
>> """
>> Disabling new line injection (3. compromise):
>> 
>> The examples we’ve used so far had only a single content line, so we 
>> couldn’t showcase the behavior yet. New lines are only injected into a 
>> multi-line string if it has at least two content lines.
>> 
>> let str_9 = """↵  
>> ····foo↵
>> ····bar↵
>> ····"""
>> 
>> let str_10 = """↵  
>> ····foo↵
>> ····bar↵
>> ····baz↵
>> ····"""
>> 
>> let string_2 = "foo\nbar"
>> let string_3 = "foor\nbar\nbaz"
>> 
>> str_9 == string_2  // => true
>> str_10 == string_3 // => true
>> To disable new line injection one would need to use the backslash for right 
>> precision.
>> 
>> let str_11 = """↵  
>> ····foo\↵
>> ····bar↵
>> ····"""
>> 
>> let str_12 = """↵  
>> ····foo\↵
>> ····bar\↵
>> ····baz↵
>> ····"""
>> 
>> str_11 == string_2    // => false
>> str_12 == string_3    // => false
>> 
>> str_11 == "foorbar"   // => true
>> str_12 == "foobarbaz" // => true
>> Remember that the last content line sn does not automatically inject a new 
>> line into the final string!
>> 
>> New line injection except for the last line (4. compromise):
>> 
>> The standard string literal like "foo" only contains its string content from 
>> the starting delimiter to the closing delimiter. The discussion on the 
>> mailing list suggests that the multi-line string literal should also go that 
>> route and not inject a new line for the last content line sn. str_9 is a 
>> good example for that behavior. 
>> 
>> Now if one would want a new line at the end of the string, there are a few 
>> options to achieve this:
>> 
>> // Natural way:
>> let str_13 = """↵  
>> ····foo↵
>> ····bar↵
>> ····↵
>> ····"""
>> 
>> // Remember the last content line does not inject a `\n` character by default
>> // so there is no need for `\n\` here (but it's possible as well)!
>> let str_14 = """↵  
>> ····foo↵
>> ····bar\n↵
>> ····"""
>> 
>> str_13 == "foo\nbar\n" // => true
>> At first glance the behavior in str_13 seems odd and inconsistent, however 
>> it actually mimics perfectly the natural way of writing text paragraphs.
>> 
>> [here is a blank line]↵
>> text text text tex text↵
>> text text text tex text↵
>> [here is a blank line]
>> This is easily expressed with the literal model expressed above:
>> 
>> let myParagraph = """↵
>> ····↵
>> ····text text text tex text↵
>> ····text text text tex text↵
>> ····↵
>> ····"""
>> 
>> 
>> 
>> -- 
>> Adrian Zubarev
>> Sent with Airmail
>> 
>> Am 13. April 2017 um 02:39:51, Xiaodi Wu (xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>) schrieb:
>> 
>>> On Wed, Apr 12, 2017 at 5:20 PM, Brent Royal-Gordon <br...@architechies.com 
>>> <mailto:br...@architechies.com>> wrote:
>>> Wow, maybe I shouldn't have slept.
>>> 
>>> Okay, let's deal with trailing newline first. I'm *very* confident that 
>>> trailing newlines should be kept by default. This opinion comes from lots 
>>> of practical experience with multiline string features in other languages. 
>>> In practice, if you're generating files in a line-oriented way, you're 
>>> usually generating them a line at a time. It's pretty rare that you want to 
>>> generate half a line and then add more to it in another statement; it's 
>>> more likely you'll interpolate the data. I'm not saying it doesn't happen, 
>>> of course, but it happens a lot less often than you would think just 
>>> sitting by the fire, drinking whiskey and musing over strings.
>>> 
>>> I know that, if you're pushing for this feature, it's not satisfying to 
>>> have the answer be "trust me, it's not what you want". But trust me, it's 
>>> not what you want.
>>> 
>>> This is not a very good argument. If you are generating files in a 
>>> line-oriented way, it is the function _emitting_ the string that handles 
>>> the line-orientedness, not the string itself. That is the example set by 
>>> `print()`:
>>> 
>>> ```
>>> print("Hello, world!") // Emits "Hello, world!\n"
>>> ```
>>> 
>>> Once upon a time, if I recall, this function was called `println`, but it 
>>> was renamed. This particular example demonstrates why keeping trailing 
>>> newlines by default is misguided:
>>> 
>>> ```
>>> print(
>>>   """
>>>   Hello, world!
>>>   """
>>> )
>>> ```
>>> 
>>> Under your proposed rules, this emits "Hello, world!\n\n". It is almost 
>>> certainly not what you want. Instead, it is a misguided attempt by the 
>>> designers of multiline string syntax to do the job that the designers of 
>>> `print()` have already accounted for.
>>> 
>>> If we were to buy your line of reasoning and adapt it for single-line 
>>> strings, we would arrive at a rather absurd result. If you're emitting 
>>> multiple single-line strings, you almost certainly want a space to separate 
>>> them. Again this is exemplified by the behavior of `print()`:
>>> 
>>> ```
>>> print("Hello", "Brent!")
>>> ```
>>> 
>>> This emits "Hello Brent!" (and not "HelloBrent!"). But we do not take that 
>>> reasoning and demand that "This is my string" end with an default trailing 
>>> space, nor do we have `+` concatenate strings by default with a separating 
>>> space.
>>> 
>>> 
>>> Moving to the other end, I think we could do a leading newline strip *if* 
>>> we're willing to create multiline and non-multiline modes—that is, newlines 
>>> are _not allowed at all_ unless the opening delimiter ends its line and the 
>>> closing delimiter starts its line (modulo indentation). But I'm reluctant 
>>> to do that because, well, it's weird and complicated. I also get the 
>>> feeling that, if there's a single-line mode and a multi-line mode, we ought 
>>> to treat them as truly orthogonal features and allow `"`-delimited strings 
>>> to use multi-line mode, but I'm really not convinced that's a good idea.
>>> 
>>> (Note, by the way, that heredocs—a *really* common multiline string 
>>> design—always strip the leading newline but not the trailing one.)
>>> 
>>> Adrian cited this example, where I agree that you really don't want the 
>>> string to be on the same line as the leading delimiter:
>>> 
>>> let myReallyLongXMLConstantName = """<?xml version="1.0"?>
>>>                                      <catalog>
>>>                                         <book id="bk101" empty="">
>>>                                            <author>John Doe</author>
>>>                                            <title>XML Developer's 
>>> Guide</title>
>>>                                            <genre>Computer</genre>
>>>                                            <price>44.95</price>
>>>                                         </book>
>>>                                      </catalog>\
>>>                                      """        
>>> 
>>> But there are lots of places where it works fine. Is there a good reason to 
>>> force an additional newline in this?
>>> 
>>> case .isExprSameType(let from, let to):
>>> return """checking a value with optional type \(from) against dynamic type 
>>> \(to) \
>>>       succeeds whenever the value is non-'nil'; did you mean to use '!= 
>>> nil'?\
>>>       """
>>> 
>>> I mean, we certainly could, but I'm not convinced we should. At least, not 
>>> yet.
>>> 
>>> In any case, trailing newline definitely stays. Leading newline, I'm still 
>>> thinking about.
>>> 
>>> As for other things:
>>> 
>>> * I see zero reason to fiddle with trailing whitespace. If it's there, it 
>>> might be significant or it might not be. If we strip it by default and we 
>>> shouldn't, the developer has no way to protect it. Let's trust the 
>>> developer. (And their tooling—Xcode, I believe Git, and most linters 
>>> already have trailing whitespace features. We don't need them too.)
>>> 
>>> * Somebody asked about `"""`-delimited heredocs. I think it's a pretty 
>>> syntax, but it's not compatible with single-line use of `"""`, and I think 
>>> that's probably more important. We can always add heredocs in another way 
>>> if we decide we want them. (I think `#to(END)` is another very Swifty 
>>> syntax we could use for heredocs--less lightweight, but it gives us a 
>>> Google-able keyword.)
>>> 
>>> * Literal spaces and tabs cannot be backslashed. This is really important 
>>> because, if you see a backslash after the last visible character in a line, 
>>> you can't tell just by looking whether the next character is a space, tab, 
>>> or newline. So the solution is, if it's not a newline, it's not valid at 
>>> all.
>>> 
>>> I'll respond to Jarod separately.
>>> 
>>>> On Apr 12, 2017, at 12:07 PM, John Holdsworth <m...@johnholdsworth.com 
>>>> <mailto:m...@johnholdsworth.com>> wrote:
>>>> 
>>>> Finally.. a new Xcode toolchain 
>>>> <http://johnholdsworth.com/swift-LOCAL-2017-04-12-a-osx.tar.gz> is 
>>>> available largely in sync with the proposal as is.
>>>> (You need to restart Xcode after selecting the toolchain to restart 
>>>> SourceKit)
>>>> 
>>>> I personally am undecided whether to remove the first line if it is empty. 
>>>> The new
>>>> rules are more consistent but somehow less practical. A blank initial line 
>>>> is almost
>>>> never what a user would want and I would tend towards removing it 
>>>> automatically.
>>>> This is almost what a user would it expect it to do.
>>>> 
>>>> I’m less sure the same applies to the trailing newline. If this is a 
>>>> syntax for
>>>> multi-line strings, I'd argue that they should normally be complete lines -
>>>> particularly since the final newline can so easily be escaped.
>>>> 
>>>>         let longstring = """\
>>>>             Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed 
>>>> do eiusmod \
>>>>             tempor incididunt ut labore et dolore magna aliqua. Ut enim ad 
>>>> minim veniam, \
>>>>             quis nostrud exercitation ullamco laboris nisi ut aliquip ex 
>>>> ea commodo consequat.\
>>>>             """
>>>> 
>>>>         print( """\
>>>>             Usage: myapp <options>
>>>>             
>>>>             Run myapp to do mything
>>>>             
>>>>             Options:
>>>>             -myoption - an option
>>>>             """ )
>>>> 
>>>> (An explicit “\n" in the string should never be stripped btw)
>>>> 
>>>> Can we have a straw poll for the three alternatives:
>>>> 
>>>> 1) Proposal as it stands  - no magic removal of leading/training blank 
>>>> lines.
>>>> 2) Removal of a leading blank line when indent stripping is being applied.
>>>> 3) Removal of leading blank line and trailing newline when indent 
>>>> stripping is being applied.
>>>> 
>>>> My vote is for the pragmatic path: 2)
>>>> 
>>>> (The main intent of this revision was actually removing the link between 
>>>> how the
>>>> string started and whether indent stripping was applied which was 
>>>> unnecessary.)
>>>> 
>>>>> On 12 Apr 2017, at 17:48, Xiaodi Wu via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> Agree. I prefer the new rules over the old, but considering common use 
>>>>> cases, stripping the leading and trailing newline makes for a more 
>>>>> pleasant experience than not stripping either of them.
>>>>> 
>>>>> I think that is generally worth prioritizing over a simpler algorithm or 
>>>>> even accommodating more styles. Moreover, a user who wants a trailing or 
>>>>> leading newline merely types an extra one if there is newline stripping, 
>>>>> so no use cases are made difficult, only a very common one is made more 
>>>>> ergonomic.
>>>> 
>>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
>>> 
>>> 
>> 
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to