4 ms·
Maybe if you've never tried formatting a traditional multiline string (e.g. in Python, C++ or Rust) before. If it isn't obvious, the problem is that you can't
by IshKebab 1y ago
Maybe if you've never tried formatting a traditional multiline string (e.g. in Python, C++ or Rust) before.
If it isn't obvious, the problem is that you can't indent them properly because the indentation becomes part of the string itself.
Some languages have magical "removed the indent" modes for strings (e.g. YAML) but they generally suck and just add confusion. This syntax is quite clear (at least with respect to indentation; not sure about the trailing newline - where does the string end exactly?).
- konart 1y agoI may be missing something but come Go has a simple: `A simple formatted string ` ?
- rybosome 1y agoYours is rendered as: A\n\tsimple\n\t\tformatted\n\t\t\tstring\n\t If you wanted it without the additional indentation, you’d need to use a function to strip that out. Typescript has dedent which goes in front of the template string, for example. I guess in Zig that’s not necessary which is nice.
- deleted 1y ago[deleted]
- konart 1y agoOkay I get it now. Formatted multiline string in code without an actual formatting and no string concat.
- xigoi 1y agoThe problem is that usually you have something like fn main() { if something { print(`A simple formatted string`) } } which looks ugly and confusing.
- z_open 1y agoEven if we ignore solutions other languages have come up with, it's even worse that they landed on // for the syntax given that it's apparently used the same way for real comments.
- n42 1y ago> it's even worse that they landed on // for the syntax .. it is using \\
- hinkley 1y agoI worked with browsers since before most people knew what a browser was and it will never cease to amaze me how often people confuse slash and backslash, / and \ It’s some sort of mental glitch that a number of people fall into and I have absolutely no idea why.
- deleted 1y ago[deleted]
- Twey 1y agoI wonder if it's dyslexia-adjacent. Dyslexic people famously have particular difficulty distinguishing rotated and reflected letterforms.
- hinkley 1y agoCould be. The frequency is such that it could be dyslexics. It's not all the time, but it's a steady rate of incidence.
- quesera 1y agoI think in the 90's it was just people repeating a pattern they learned from Windows/DOS. It used to grate on my nerves to hear people say, e.g. "H T T P colon backslash backslash yahoo dot com". But I think they always typed forward slash, like they knew the correct slash to use based on the context, but somehow always spoke it in DOSish.
- Blackarea 1y agoWe can just use a crate for that and don't have to have this horrible comment like style that brings its own category of problems. https://docs.rs/indoc/latest/indoc/ https://docs.rs/indoc/latest/indoc/
- Twey 1y agoAnd what if you do want to include two spaces at the beginning of the block (but not any of the rest of the indentation)? Choice of specific line-start marker aside, I think this is the best solution to the indented-string problem I've seen so far.
- gf000 1y agoI think Java's solution is much cleaner.
- IshKebab 1y agoFor those of us that haven't used Java for a decade... > In text blocks, the leftmost non-whitespace character on any of the lines or the leftmost closing delimiter defines where meaningful white space begins. From https://blogs.oracle.com/javamagazine/post/text-blocks-come-to-java https://blogs.oracle.com/javamagazine/post/text-blocks-come-... It's not a bad option but it does mean you can't have text where every line is indented. This isn't uncommon - e.g. think about code generation of a function body.
- norir 1y agoSignificant whitespace is not difficult to add to a language and, for me, is vastly superior than what zig does both for strings and the unnecessary semicolon that zig imposes by _not_ using significant whitespace. I would so much rather read and write: let x = """ a multiline string example """ than let x = //a //multiline string //example ; In this particular example, zig doesn't look that bad, but for longer strings, I find adding the // prefix onerous and makes moving strings around different contexts needlessly painful. Yes, I can automatically add them with vim commands, but I would just rather not have them at all. The trailing """ is also unnecessary in this case, but it is nice to have clear bookends. Zig by contrast lacks an opening bracket but requires a closing bracket, but the bracket it uses `;` is ambiguous in the language. If all I can see is the last line, I cannot tell that a string precedes it, whereas in my example, you can. Here is a simple way to implement the former case: require tabs for indentation. Parse with recursive descent where the signature is (source: string, index: number, indent: number, env: comp_env) => ast Multiline string parsing becomes a matter of bumping the indent parameter. Whenever the parser encounters a newline character, it checks the indentation and either skips it, or if is less than the current indentation requires a closing """ on the next line at a reduced indentation of one line. This can be implemented in under 200 lines of pure lua with no standard library functions except string.byte and string.sub. It is common to hear complaints about languages that have syntactically significant whitespace. I think a lot of the complaints are fair when the language does not have strict formatting rules: python and scala come to mind as examples that do badly with this. With scala, practically everyone ends up using scalafmt which slows down their build considerably because the language is way too permissive in what it allows. Yaml is another great example of significant whitespace done poorly because it is too permissive. When done strictly, I find that a language with significant whitespace will always be more compact and thus, in my opinion, more readable than one that does not use it. I would never use zig directly because I do not like its syntax even if many people do. If I was mandated to use it, I would spend an afternoon writing a transpiler that would probably be 2-10x faster than the zig compiler for the same program so the overhead of avoiding their decisions I disagree with are negligible. Of course from this perspective, zig offers me no value. There is nothing I can do with zig that I can't do with c so I'd prefer it as a target language. Most code does not need to be optimized, but for the small amount that does, transpiling to c gives me access to almost everything I need in llvm. If there is something I can't get from c out of llvm (which seems highly unlikely), I can transpile to llvm instead.
- deleted 1y ago[deleted]
- qzzi 1y agoC and Python automatically concatenate string literals, and Rust has the concat! macro. There's no problem just writing it in a way that works correctly with any indentation. No need for weird-strings. " one\n" " two\n" " three\n"
- drjeats 1y agoPersonally, I'd rather prefix with `\\` than have to postfix with `\n`. The `\\` is automatically prepended when I enter a newline in my editor after I start a multiline string, much like editors have done for C-style multiline comments for years. Snippet from my shader compiler tests (the `\` vs `/` in the paths in params and output is intentional, when compiled it will generate escape errors so I'm prodded to make everything `/`): test "shader_root_gen" { const expected = \\// Generated file! \\ \\pub const @"spriteszzz" = opaque { \\ pub const @"quadsprite" = @import("src\spriteszzz/quadsprite.glsl"); \\}; \\ \\pub const @"sprites" = opaque { \\ pub const @"universalsprite" = @import("src\sprites/universalsprite.glsl"); \\}; \\ \\pub const @"simpleshader" = @import("src/simpleshader.glsl"); \\ ; const cmdline = \\--prefix src -o testfile.zig src\spriteszzz/quadsprite.glsl src\sprites/universalsprite.glsl src/simpleshader.glsl ; var args_iter = std.mem.tokenizeScalar(u8, cmdline, ' '); const params = try Params.parseFromCmdLineArgs(&args_iter); var buffer: [expected.len * 2]u8 = undefined; var stream = std.io.fixedBufferStream(buffer[0..]); try generateSource(stream.writer().any(), params.input_files.items, params.prefix); const actual = stream.getWritten(); try std.testing.expectEqualSlices(u8, expected, actual); }