[swift-evolution] multi-line string literals

Drew Crawford drew at sealedabstract.com
Fri Dec 11 15:54:48 CST 2015


I actually like this solution, for what it’s worth.  +1 for """ vs ''' having escaped/unescaped semantics.

I considered suggesting that, but like you I suspect that clattner has a strong view.

Would be interested in hearing what him & others think.


> On Dec 11, 2015, at 10:01 AM, Travis Tilley <ttilley at gmail.com> wrote:
> 
> OK, I understand your problem better with that example. Perhaps a solution would be to have """ process escapes while ''' starts a "raw" string. This is very much in line with ruby's style of strings where processing isn't done within single quoted strings:
> 
> irb(main):001:0> foo = 2
> => 2
> irb(main):002:0> "#{foo}"
> => "2"
> irb(main):003:0> '#{foo}'
> => "\#{foo}"
> 
> (Ignore that \# at the end there; that's only because the interactive console returns a double quoted string. I assure you, the contents are unescaped.)
> 
> If we go with this syntax for escaped and unescaped strings, then for consistency's sake it would make sense to have single-line single-quoted strings that don't escape and are "raw" strings like in ruby.
> 
> CCing Chris Lattner here specifically because, in swift today, using single quotes gives you a warning to just use double quotes, so he might have a strong opinion on this one. The latest commit to Lexer.cpp was actually to add better handling of single quoted strings (and I think more warnings if I remember?).
> 
> 
> - Travis Tilley
> 
> 
> On Fri, Dec 11, 2015 at 6:01 AM, Drew Crawford <drew at sealedabstract.com> wrote:
> 
>> On Dec 11, 2015, at 1:27 AM, Travis Tilley <ttilley at gmail.com> wrote:
>> 
>> I think there are many more use cases than you suggest in #1. 
> 
> I didn’t intend this to be read narrowly, sorry!  I simply mean that I don’t have a good handle on why people want this feature, I think it might be good to investigate that question to help inform the design rather than assume everybody else is thinking of the same use case each of us individually may have in mind.  Your Docopt example was very helpful in this regard, I feel like I better understand your problems.  I agree that escaped strings are the ‘sane’ default to serve a use case like Docopt.
> 
>> As for your question #2... I believe that the sane option should always be the easiest, and the less sane option should be possible, but with "syntactic vinegar" to make it less pleasant to use.
> 
> I don’t believe this is true in full generality.  An illustration from the type system:
> 
>> let a: Int16 = 0
>> let b: Int32 = 0
>> if a & b { }
> 
> There are two ways to resolve this: the “sane” option is to promote `a` to Int32—the insane option is to demote `b` to Int16.  Swift rejects both, gives you a compile error, and tells you to sort it out yourself.
> 
> Having “default” and “optout” behavior is correct sometimes, right?  As is sending it back to the programmer for clarification.  What I’m asking is how we distinguish between those two approaches that are both correct for some problems.  Do you know any design principle that distinguishes these examples?  There must be some reason we force a programmer to rewrite their implicit upcast but not their implicit escaped string.
> 
>> Please give me more info on what would make your specific use case less unpleasant. JSON/JavaScript escape sequences tend to correspond pretty well with swift (with notable exceptions).
> 
> So for example, consider an object.json:
> 
>  {
>   "foo": "bar",
>   "baz": "bap\nbap"
> }
> 
> Now I paste that into my Swift sourcode:
> 
> let sampleJSON = """
> {
>   "foo": "bar",
>   "baz": "bap\nbap"
> }
> """
> 
> Now if Swift escapes this, and thinks I wanted:
> 
> 
> {
>   "foo": "bar",
>   "baz": "bap
> bap"
> }
> 
> 
> This is no longer valid JSON, and I get a mystery parse error.  
> 
> In the spirit of clattner’s “what do other languages do?”, I think it is instructive to look at what Pythonistas do with their Python multi-line syntax.  Almost universally, they use (the default) escaped strings to store JSON.  Even people who should know better, because they are writing a JSON parser, reach for escaped strings first.  Escaped strings work until they don’t (e.g. in the example), and then they fail *badly*.
> 
> Think about the plight of a noob Swift 3 programmer who has Python syntax.  StackOverflow questions will teach them to use escaped strings in this case.  Then they paste their JSON into a linter and it comes back valid.  Even if they go read a JSON parser they will learn to use escaped strings!  I wonder if an entire class of bugs can be avoided by being more careful with the syntax in some way.
> 
> While I am motivating the example in terms of JSON specifically, it is much broader than one format—XML, YAML, Xcode build logs, CSV—are all cases where escaping might be a surprise, particularly in playgrounds.
> 
> 



More information about the swift-evolution mailing list