[swift-evolution] multi-line string literals

Drew Crawford drew at sealedabstract.com
Fri Dec 11 05:01:46 CST 2015

> 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

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 <http://stackoverflow.com/a/1872081> to store JSON.  Even people who should know better, because they are writing a JSON parser <https://github.com/simplejson/simplejson/blob/v2.3.3/simplejson/tests/test_pass3.py#L8>, 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.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151211/548a426e/attachment.html>

More information about the swift-evolution mailing list