Zig: better multiline string syntax

Created on 26 Jul 2016  路  12Comments  路  Source: ziglang/zig

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 #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.
enhancement

Most helpful comment

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.

All 12 comments

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.

co_awg3vuaekhdy

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.

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.

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.

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.

i wonder how this passed????

\ for each line, sorry for strong wording, but this is an abomination..

People in this community needs to show more strong opinion to veto some decisions

This is not multiline string anymore, if you have to type \ each time, + it reduces visibility on the actual text

Editing the string is a pain

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.

Zig is the only language where i have to take breaks from typing because ergonomics are so bad

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.

This is not a problem in other languages, not even in C++, why should it be for ZIG? does it want to be a better C, as i read above, or does it want to do its backwards things too?

By enforcing \\, you add noise in my text, something i wanted to avoid, otherwise i'd stick with \n, what if for my scripting language, my lines start with \ ?, or maybe i just want my message to start with \ , thanks, i now have readability 0 as a built in language feature! using a character as a multiline separator

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

Why do people want to use multi line strings in the first place? maybe should have asked that question first!

I have one answser, to edit text just like i'd do in a text editor ;)

@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;`

`zig 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

```zig
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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bheads picture bheads  路  3Comments

S0urc3C0de picture S0urc3C0de  路  3Comments

andrewrk picture andrewrk  路  3Comments

jorangreef picture jorangreef  路  3Comments

jayschwa picture jayschwa  路  3Comments