[swift-evolution] Alternate proposal for multi-line string literial
Steve K. Chiu
steve.k.chiu at gmail.com
Thu Mar 24 08:46:44 CDT 2016
And it seems no one like the #let idea, then how about just reuse
typealias, or simple let?
typealias #text = #string(escape: "$")
or
let #text = #string(escape: "$")
2016-03-24 21:43 GMT+08:00 Steve K. Chiu <steve.k.chiu at gmail.com>:
>
> Perl are using heredoc notation, for example:
>
> my $message = <<'END_MESSAGE';
> void main() {
> printf("%s\n", "hello world");
> }
> END_MESSAGE
>
> or Perl6
>
> https://doc.perl6.org/language/quoting
>
> Lua's multi-line raw string look like this:
> (you can add extra = inside [[ and ]], in case the text contains [[ or ]])
>
> local message = [[
> void main() {
> printf("%s\n", "hello world");
> }
> ]]
>
> or with ]] in text:
>
> local message = [===[
> void main() {
> printf("[[%s]]\n", "hello world");
> }
> ]===]
>
> And C++11 raw string has the same mechanism as Lua (but does not remove
> first/last newline)
>
> auto message = R"(void main() {
> printf("[[%s]]\n", "hello world");
> })";
>
> or with )" in text:
>
> auto message = R"===(void main() {
> printf("(%s)", "hello world");
> })===";
>
>
> I think adding extra tag inside the string deliminator is actually a good
> idea, I would like to revise the proposal as:
>
> #string(options) ``text``
>
> And then you can add extra tag inside back-quote, just like Lua and C++11
> raw strings, so the shortest version would look like:
>
> ``^\d+``
>
> It is raw string (escape is disabled), useful for regexp immediately, and
> if you need to write `` inside the string:
>
> let message =
> `==`
> void main() {
> printf("``(%s)``", "hello world");
> }
> `==`
>
> or with options:
>
> let message =
> #string(escape: "$")
> ``
> void main() {
> printf("(%s)", "$(value)");
> }
> ``
>
>
>
>
> 2016-03-24 19:46 GMT+08:00 Step C <schristopher at bignerdranch.com>:
>
>> Happy to see someone with a proposal on this!
>>
>> > On Mar 23, 2016, at 12:49 AM, Steve K. Chiu via swift-evolution <
>> swift-evolution at swift.org> wrote:
>> >
>> > Hi,
>> >
>> > I am new to swift-evolution list, here is my draft proposal for the
>> multi-line string literal problem.
>> > The idea had been discussed in the list before, but it seems there are
>> no real solution to many of the string literal problem.
>> > Let's first define what are the problem with string literal:
>> >
>> > 1. should be able to disable escape char
>> >
>> > 2. or better, able to replace escape char with user defined char
>> Yes!
>> >
>> > 3. should be able to write multi-line string literal, and is copy-paste
>> friendly
>> >
>> > 4. for multi-line string, should be able to remove first and last
>> newline char, so user can write string in block
>> >
>> > 5. for multi-line string, should be able to remove leading indent, or
>> remove all indent
>> >
>> > 6. for multi-line string, should be able to replace newline with user
>> defined string ("\r\n", "\r", "\r", or simply " ")
>> >
>> > 7. should be able to add feature over time, without breaking existing
>> code
>> >
>> > My proposal to the above problem is to introduce new 'process
>> instruction' (not sure how to call it), in the following form:
>> >
>> > #string(options) "text"
>>
>> Building on our meaning for # as compile-time magic. Ok.
>> >
>> > for example:
>> >
>> > #string(escape: nil) "^\d+"
>> >
>> > #string(escape: "$", end: "<EOF>") "
>> > $(username),
>> > Is it 1358 yet?
>> > <EOF>"
>> >
>> > It is possible to add many options list above, and you can add more
>> options over time without breaking code.
>> >
>> > #string(
>> > escape: Character? = "\\",
>> > end: String? = nil,
>> > skipEnclosureNewline: Bool = true,
>> > skipLeadingIndent: Bool = true,
>> > skipAllIndent: Bool = false,
>> > newline: String? = nil
>> > )
>> >
>> > for 1. & 2., escape option to replace escape char, pass nil will
>> disable escape.
>> >
>> > for 3., end option for end-of-string mark, pass nil will disable
>> multi-line processing.
>> >
>> > for 4., skipEnclosureNewline will skip newline if it is the first or
>> last char of the string.
>> >
>> > for 5., skipLeadingIndent will skip leading indent, leading indent is
>> the leading white-spaces of first line of multi-line string.
>> >
>> > for 5., skipAllIndent will skip all indent, this will override
>> skipLeadingIndent.
>> >
>> > for 6., newline option to replace newline char in multi-line string,
>> pass nil will disable the replacement (as-is in the source).
>> >
>> > But there are one problem remain, as you can see, the #string with
>> options will become very long; I don't think it is a pleasure to use such
>> expression except for one time literal. To fix the problem, I propose yet
>> another process instruction:
>> >
>> > #let #rex = #string(escape: nil)
>> > #let #mail = #string(escape: "$", end: "<EOF>")
>> >
>> > Now you can write the string as:
>> >
>> > #rex "^\d+"
>> >
>> > #mail "
>> > $(username),
>> > Is it 1358 yet?
>> > <EOF>"
>> >
>> > #let should be able to be used with other # process instruction as
>> well, for example, #available, among other things.
>> >
>> > What do you think?
>>
>> I'd like to see a comparison to how other languages, particularly Perl,
>> handle this. I like Chris Lattner's vision for this to be the power-user
>> version of string literals. As you identified, a problem with this solution
>> is verbosity / noisiness. I don't like the #let #token syntax on first
>> blush - seems macro-ish to me. But I don't have a better suggestion right
>> now. Hmmm.
>>
>>
>> >
>> >
>> > _______________________________________________
>> > swift-evolution mailing list
>> > swift-evolution at swift.org
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160324/7afcb118/attachment.html>
More information about the swift-evolution
mailing list