Live data from Hacker News

Zig's Lovely Syntax

matklad.github.io

131–140 of 246 posts

Re: Zig's Lovely Syntax

#131

Earlier quoted context omitted.

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 i…

We 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/

And 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.

Re: Zig's Lovely Syntax

#132

Earlier quoted context omitted.

Because to use lambdas you're asking the language to make implicit heap allocations for captured variables. Zig has a policy that all allocation and control flow are explicit and visible in the code, which you call re-inventing the wheel. Lambdas are great for convenience and productivity. Eventually they can lead to memory cycles and leaks. The side-effect is that software starts to consume gigabytes of memory and m…

Nothing about lambdas requires heap allocation. See also: C++, Rust

If the lambda captures some value, and also outlives the current scope, then that captured value has to necessarily be heap allocated.

Re: Zig's Lovely Syntax

#133

Since we're talking syntax... it's mildly infuriating that the zig parser is not smart enough to understand expressions like `const x=a()orelse b();`. You have to manually add a space before `orelse` -- but isn't that what `zig fmt` is for? I have RSI and it's maddening having to mash the arrow keys and add/remove whitespace until the parser is happy. I've heard the argument that people might confuse binary operators…

No idea why it wouldn't add the space, but you could configure your editor to always add a space after `)` and let zig fmt remove the space when not needed.

Re: Zig's Lovely Syntax

#134
post #87

Earlier quoted context omitted.

Why would capturing require a heap allocation? Neither Rust nor C++ do this.

You need to store the captured data somewhere if the lambda is called after the outer function returns. AFAIK C++ (or rather std::function) will heap-allocate if the capture size goes above some arbitrary limit (similar to small-string optimizations in std::string). Not sure how Rust handles this case, probably through some "I can't let you do that, Dave" restrictions ;)

But that's not a closure, a closure/lambda is not an std::function. It's its own type, basically syntactic sugar for a struct with the captures vars and operator().

Of course if you want to store it on a type-erased container like std::function then you may need to heap allocate. Rust's equivalent would be a Box.

Re: Zig's Lovely Syntax

#135
post #96
post #81

Earlier quoted context omitted.

By adopting a syntax like fn add(x: i32, i32) i32 they have said perma-goodbye to lambdas. They should have at-least considered fn add(x: i32, i32): i32

They could still fix it with arrow functions, but it’s always gonna look weird. Some other people have tried to explain how they prefer types before variable declarations, and they’ve done a decent job of it, but it’s the function return type being buried that bothers me the most. Since I read method signatures far more often than method bodies. fn i32 add(…) is always going to scan better to me.

OK, but with generics return type first tends to becomes a monster.

Re: Zig's Lovely Syntax

#136
post #124

Earlier quoted context omitted.

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 i…

I may be missing something but come Go has a simple: `A simple formatted string ` ?

Yours 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.

Re: Zig's Lovely Syntax

#137
post #54

> Raw or multiline strings are spelled like this: const still_raw = \\const raw = \\ \\Roses are red \\ \\ Violets are blue, \\ \\Sugar is sweet \\ \\ And so are you. \\ \\ \\; \\ ; This syntax seems fairly insane to me.

Visually I dislike the \\, but I see this solves the problem of multiline literals and indentation in a handy, unambiguous way. I’m not actually aware of any other language which solves this problem without a function.

Re: Zig's Lovely Syntax

#138
post #117
post #110

Earlier quoted context omitted.

> it's not the kind of surface level "aesthetically beautiful" readability that tickles the mind of an abstract thinker Rather, the sort of beauty it's going for here is exactly the type of beauty that requires a bit of abstraction to appreciate: it's not that the concrete syntax is visually beautiful per se so much as that it's elegantly exposing the abstract syntax, which is inherently more regular and unambiguous…

I considered making the case for the parallels to Lisp, but it's not an easy case to make. Zig is profoundly not a Lisp. However, in my opinion it embodies a lot of the spirit of it. A singular syntax for programming and metaprogramming, built around an internally consistent mental model. I don't really know how else to put it, but it's vaguely like a C derived spiritual cousin of Lisp with structs instead of lists.

I think because of the forces I talked about above we experience a repeating progression step in programming languages:

- we have a language with a particular philosophy of development

- we discover that some concept A is awkward to express in the language

- we add a special case to the language to make it nicer

- someone eventually invents a new base language that natively handles concept A nicely as part of its general model

Lisp in some sense skipped a couple of those progressions: it had a very regular language that didn't necessarily have a story for things that people at the time cared about (like static memory management, in the guise of latency). But it's still a paragon of consistency in a usable high-level language.

I agree that it's of course not correct to say that Zig is a descendent or modern equivalent of Lisp. It's more that the virtue that Lisp embodies over all else is a universal goal of language design, just one that has to be traded off against other things, and Zig has managed to do pretty well at it.

Re: Zig's Lovely Syntax

#139

Earlier quoted context omitted.

Nothing about lambdas requires heap allocation. See also: C++, Rust

If the lambda captures some value, and also outlives the current scope, then that captured value has to necessarily be heap allocated.

That would be a bug, so just... don't do that?

If you return a pointer to a local variable that outlives the scope, the pointer would be dangling. Does that mean we should ban pointers?

If you close over a pointer to a local variable that outlives the scope, the closure would be dangling. Does that mean we should ban closures?

Re: Zig's Lovely Syntax

#140
post #12

> Like Rust, Zig uses 'name' (':' Type)? syntax for ascribing types, which is better than Type 'name' I'm definitely an outlier on this given the direction all syntactically C-like new languages have taken, but I have the opposite preference. I find that the most common reason I go back to check a variable declaration is to determine the type of the variable, and the harder it is to visually find that, the more annoy…

I much prefer Pascal typing because it

1. Allows type inference without a hacky 'auto' workaround like c++ and 2. Is less ambiguous parsing wise. I.e. when you read 'MyClass x', MyClass could be a variable (in which case this is an error) or a type; it's impossible to know without context!

Post reply on HN