Skip to content
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

better multiline string syntax #162

Closed
andrewrk opened this issue Jul 26, 2016 · 13 comments
Closed

better multiline string syntax #162

andrewrk opened this issue Jul 26, 2016 · 13 comments
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase.
Milestone

Comments

@andrewrk
Copy link
Member

After discussing with @thejoshwolfe, I believe we can do even better than status quo multiline strings (See #76) which are C++ style.

This proposal is to remove the existing multiline string support and replace it with a new syntax.

Old syntax, with an example taken from tetris:

as.primitive = create_shader(r"VERT(#version 150 core

in vec3 VertexPosition;

uniform mat4 MVP;

void main(void) {
    gl_Position = vec4(VertexPosition, 1.0) * MVP;
})VERT", r"FRAG(#version 150 core

out vec4 FragColor;

uniform vec4 Color;

void main(void) {
    FragColor = Color;
})FRAG", null);

New syntax proposal:

as.primitive = create_shader(
    \\#version 150 core
    \\
    \\in vec3 VertexPosition;
    \\
    \\uniform mat4 MVP;
    \\
    \\void main(void) {
    \\    gl_Position = vec4(VertexPosition, 1.0) * MVP;
    \\}
,
    \\#version 150 core
    \\
    \\out vec4 FragColor;
    \\
    \\uniform vec4 Color;
    \\
    \\void main(void) {
    \\    FragColor = Color;
    \\}
, null);

Simpler example:

const abc =
    \\one
    \\two
    \\three
;

This is equivalent to: const abc = "one\ntwo\nthree"; Note that the idiom of adding ++ "\n" may become common practice.

Rationale:

  • Maintain the indentation of the outer code and inner string while having precise control over the contents of the multiline string.
  • With the cooperation of Proposal: remove multiline comments #161, text editors can correctly syntax highlight on a line-by-line basis, without having to look at surrounding lines for context. Another way of putting this is that humans and computers both can look at an individual line and parse it semantically.
  • \\ looks similar to // which indicates a comment to the end of the line, just as \\ indicates a part of a multiline string to the end of the line.
  • Modern text editors make it easy to paste a document and then prefix a character or two to the beginning of every line.
@andrewrk andrewrk added the enhancement Solving this issue will likely involve adding new logic or components to the codebase. label Jul 26, 2016
@andrewrk andrewrk added this to the 0.1.0 milestone Jul 26, 2016
@andrewrk
Copy link
Member Author

2 things we didn't consider yet:

  • C string syntax. Without explicit C multiline string syntax, users must do something like:
const multiline_null_term_string =
    c"one\n" ++
    c"two\n" ++
    c"three\n" ++
    c"four\n";

It's tempting to say, well then, that's what you get for using C. But C isn't going away for a long time, and part of Zig's strategy is to make Zig better at writing C code than C is at writing C code. So we should probably have a notation for C multiline strings.

Here's one proposal:

const multiline_null_term_string =
    c\\one
    c\\two
    c\\three
;

Now, point 2 that we didn't consider yet:

  • The other reason we have raw strings is for non-multiline strings that are awkward to have escapes in them. For example regexes:
const re = compile_regex(r"#(".*"/aaa)#");

Our new syntax proposal is maybe suboptimal for this use case:

const re = compile_regex(
    \\".*"/aaa
;

Or maybe not. It takes 3 lines instead of 1, but maybe that's actually reasonable.

One constraint that I feel comfortable stating is that we should not have both of these multiline string syntaxes. It's already enough that we have single-line strings that support escapes as well as multiline strings with no escapes, so let's keep it to 2, and not 3.

@andrewrk
Copy link
Member Author

andrewrk commented Aug 5, 2016

co_awg3vuaekhdy

@Meai1
Copy link

Meai1 commented Jul 25, 2018

I think this is so much harder to read over all these extra chars, not copy pasteable as easily anymore and the main reason seems to be to make the job of the compiler/parser easier which is quite unimportant in my opinion. Now you better pray that your text editor has a column selection mode or this is going to be all kinds of painful. Or you better have perfect ziglang support for a shortcut in your IDE to un-multiline them all on one go.

@thejoshwolfe
Copy link
Sponsor Contributor

Yeah you should have a column mode in your editor.

This isn't just about readability for a compiler. This also makes it easier for humans to read, especially when it's a very large string literal, say over 100 lines long.

But the biggest win for this syntax is that indentation inside the string is decoupled from indentation outside the string.

@andrewrk
Copy link
Member Author

This design decision is locked in, stable, and will not change. It's one of the syntax decisions that I'm most happy with about Zig.

@Meai1
Copy link

Meai1 commented Jul 25, 2018

Okay I'm sad to hear that because I can't disagree strongly enough. More characters is almost always worse in my opinion, your brain has to parse more even if it's just subconsciously. Saying that it's easier to read makes no sense to me, especially when it's a large text because then it's even more obvious that it's an external non-zig content... without the // in front... you are reading the original text. How can the original text be hard to read, it's the original. I hope you will revisit this before 1.0 even though you said that it's a closed issue now, thanks.

@alexnask
Copy link
Contributor

alexnask commented Nov 6, 2020

I strongly disagree, this is the only multiline string literal syntax that I've encountered where dealing with indentation levels is not a PITA.
I find that this easily outweighs the disadvantages, especially if you are using a text editor with multi-cursor support.

@jedisct1
Copy link
Contributor

jedisct1 commented Nov 6, 2020

I like the multi-line syntax a lot as well.

And text editors can be configured to automatically propagate \\ to the next line just like what they do with C comments.

@pfgithub
Copy link
Contributor

pfgithub commented Nov 7, 2020

@RUSshy Does @embedFile() work for you? If you need long multiline strings, it can be more readable and editable than embedding the text in source code

or maybe i just want my message to start with \

Status quo multiline string syntax imo handles this better than many other languages because zig doesn't allow escapes in multiline strings.

const example_script = `
if(true) {
   console.log("newline: \\n, backslash: \\\\");
   const embedded_multiline_string = \`\`;
}
`
const newlines_with_backslashes = `\\something;
\\something_else;`
const example_script =
    \\if(true) {
    \\   console.log("newline: \n, backslash: \\");
    \\   const embedded_multiline_string = ``;
    \\}
;
const newlines_with_backslashes = 
    \\\something;
    \\\something_else;
;

In zig, pasting text into a multiline string requires inserting \\ at the beginning of each line. In Javascript, you instead have to fix backslashes and backticks in the pasted code, and have to have the code not match with the rest of your file's indentation. imo zig made a good tradeoff here.

I would have understood if you had choosen \n instead of \ at least it would have made "logical" sense

const example_script =
    \nconsole.log("newline: \n, backslash: \\");
    \nconst embedded_multiline_string = ``;
;

Without syntax highlighting, this is a bit unreadable. Also, it implies there is a newline before the top line when there isn't.

@ziglang ziglang deleted a comment Nov 7, 2020
@3yggy
Copy link

3yggy commented Jun 2, 2021

The clear solution is to use an up-high-line escape \^ where the preceding new line is undesirable.

@ziglang ziglang locked as resolved and limited conversation to collaborators Jun 2, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase.
Projects
None yet
Development

No branches or pull requests

8 participants
@thejoshwolfe @andrewrk @jedisct1 @alexnask @Meai1 @pfgithub @3yggy and others