Live data from Hacker News

Interview with Zig language creator Andrew Kelley [video]

youtube.com

161–170 of 210 posts

Re: Interview with Zig language creator Andrew Kelley [video]

#161

Earlier quoted context omitted.

I'm not 100% confident I follow, but this sounds like one of those backflips Rust programmers do to satisfy the borrow checker. As in, you wouldn't write the code this way if you didn't have to. You do get memory safety in return... but you can see where the desire for a more eloquent approach might arise.

For a moment I thought Sam Altman was spending his time reading random HN forums and commenting on the intricacies of Rust coding. Took me a minute to catch the missing "l" in your handle ;)

haha I'm not sama and have been using this handle, and variants, for longer than he's been alive.

But you're not the first to think so!

Re: Interview with Zig language creator Andrew Kelley [video]

#162

Earlier quoted context omitted.

Can you explain how this is a problem in modern C++? I was under the impression that all the STL containers (string, vector, list, map, etc.) worked the same and have an allocator parameter. Are there other areas where these are missing? Or is the issue that STL implementations almost always default to an allocator that uses malloc? I'm not trying to dog on Zig here (it's a nice little language) but this just doesn't…

Many core modern C++ types don't permit customizing the allocator. E.g. std::function

However, most std::functions have a small built-in buffer for captured variables, like 4 pointers worth. If you limit yourself to only capturing that many, there's no allocation.

Re: Interview with Zig language creator Andrew Kelley [video]

#163

I work in HFT, and one of the key concerns when writing low-latency code is "is this code allocating memory, and if so, how can I stop it?" Zig is the perfect language for this use case as none of the standard library implicitly allocates, rather for anything that allocates, the caller must pass in an allocator. The stdlib also provides a handy arena allocator, which is often the best choice. This is a huge advantage…

There is some ongoing work towards custom allocators for containers in Rust std. [1] Right now you could also go no_std (you still get the core library, which does not contain any allocating data structures) and use custom containers with a passed in allocator. Zig is definitely a cool language, and it will be interesting if they can come up with good solutions to memory management! But sentences like these in the do…

That is pretty common in low level domains. Rust instead comes with complexity of borrowck and lifetimes management no matter how rustaceans say it is second nature.

Re: Interview with Zig language creator Andrew Kelley [video]

#164
post #117
post #105

Earlier quoted context omitted.

I do love how zig's comptime naturally led to generics without extra syntax. But after using nim i'm convinced that macros make even more sense for systems programming. They can even affect performance -- nim's macros can generate types that would be difficult to write by hand. I also take issue with your statement that zig is "more minimal" since that only applies to the user's perspective -- from the compiler's per…

> But after using nim i'm convinced that macros make even more sense for systems programming. Macros are controversial. I love them in Scheme and Clojure, but I wouldn't want them in any language aimed at a larger, more mainstream crowd. At the very least, macros introduce another meta-language to know (and if they're in a language with a complex type-level language like Rust or Haskell then they're a third language…

Look at any sufficiently complex and/or low level C like Linux or FreeRTOS, and C text macros are used significantly. Some of the functionality would be horrible to implement otherwise. Being text based they're a pain, but like @gw, I'd have a hard time seeing a language like Zig without macros making a good low level system language. Maybe a good systems application like Kubernetes, similar to Go's niche, but not system kernels.

Re: Interview with Zig language creator Andrew Kelley [video]

#165
post #14

What is the best way to start with zig, if you know C by heart? I had a look a while ago, but I feel I miss out how the concepts are to be used in practice.

If you want to be eased into the language, start by checking out https://ziglearn.org . Otherwise just take a look at the overview on the homepage of https://ziglang.org , then the docs. After that you should already be in great shape and you can read the standard library for examples of useful patterns.

Is the https://ziglearn.org site up to date with the latest versions of the language and standard library? The initial "Hello, World" example fails to compile for me. I get:

Semantic Analysis [533/803] ./main.zig:4:14: error: container 'std.debug' has no member called 'print' std.debug.print("Hello, {}!\n", .{"World"});

Re: Interview with Zig language creator Andrew Kelley [video]

#166
post #137

Earlier quoted context omitted.

> But sentences like these in the documentation [2] would make me prefer Rust for most low level domains While such use-after-free issues are not prevented at compile time, the plan is to ultimately have safe Zig catch them (and panic) at runtime, i.e. safe Zig shouldn't have undefined behaviour. Because this is done with runtime checks, the expectation is that those checks will be turned off (selectively, perhaps) i…

> but those guarantees come at a significant cost -- to language complexity and compilation time Aren't Rust's compilation time woes more due to the amount of IR the front/middle-end give to LLVM? I was under the impression that the type system-related stuff isn't that expensive.

The borrow-checking and ownership mechanism is cheap, and it's almost never a significant part of the big compilation time encountered in Rust.

What's not cheap, and is responsible for long compilation times (the order is arbitrary, the relative weights are highly dependent of the code-base):

- size of the code generation units (the whole crate vs individual files in C)

- procedural macros

- generics & traits

- interaction between generics & LLVM IR generation (a lot of bloat is created, to be removed by LLVM later)

- LLVM itself

Most of those are being worked on, but in the end it's mostly a social problem: as Rust users are used to long compile time, many of them don't especially take care of it, and most gains in the compiler are often outweighed by people writing slower code. It's already possible to write Rust code that compiles quickly, if you pay attention. The culture is evolving though, and more and more library authors are now mindful of compilation time of their crate (and the tooling to diagnose it is also improving).

Key takeaway: Memory safety isn't what makes Rust compile slowly, “zero-cost abstractions” is.

Re: Interview with Zig language creator Andrew Kelley [video]

#167

Earlier quoted context omitted.

> but those guarantees come at a significant cost -- to language complexity and compilation time Aren't Rust's compilation time woes more due to the amount of IR the front/middle-end give to LLVM? I was under the impression that the type system-related stuff isn't that expensive.

The borrow-checking and ownership mechanism is cheap, and it's almost never a significant part of the big compilation time encountered in Rust. What's not cheap, and is responsible for long compilation times (the order is arbitrary, the relative weights are highly dependent of the code-base): - size of the code generation units (the whole crate vs individual files in C) - procedural macros - generics & traits - inter…

> Memory safety isn't what makes Rust compile slowly, “zero-cost abstractions” is.

What one of Rust's designers told me when I asked him why they made the language so complicated is that nearly all of Rust's features exist to serve the borrow checker (except maybe macros). Once you have those features, and because Rust is a low-level language, you must have "zero-cost abstractions."

I don't know whether some other hypothetical low-language language could exist that gives you both sound compile-time memory safety guarantees as well as be a simple language that compiles quickly -- I would love to evaluate such a language, but we don't have one right now.

Re: Interview with Zig language creator Andrew Kelley [video]

#168
post #147
post #137

Earlier quoted context omitted.

> But sentences like these in the documentation [2] would make me prefer Rust for most low level domains While such use-after-free issues are not prevented at compile time, the plan is to ultimately have safe Zig catch them (and panic) at runtime, i.e. safe Zig shouldn't have undefined behaviour. Because this is done with runtime checks, the expectation is that those checks will be turned off (selectively, perhaps) i…

> In that case, the guarantees aren't as strong as Rusts, but those guarantees come at a significant cost -- to language complexity and compilation time -- that can also have a negative effect on correctness How would those guarantees have a negative effect on correctness? Are you thinking something like, you need to design your data structure / program in a non-intuitive way that makes it more difficult to get the l…

Because a complex language is harder to read, and so slower to read and understand, and so to maintain over time without introducing bugs; compilation speed also slows you down, which means you write fewer tests. In general, getting a correct program requires effort. If that effort goes elsewhere, there's less of it for correctness.

Re: Interview with Zig language creator Andrew Kelley [video]

#169
post #135

Earlier quoted context omitted.

> Regarding the PR you just sent, I'd like to hear why you think it cannot be applied to C? I didn't mean that a safe allocator cannot be used in C; I meant that C cannot be made memory safe in its entirety as simply as Zig can. Why? Because C has pointer arithmetic while (safe) Zig doesn't, Zig has slices while C doesn't, and C has non-typesafe casts while safe Zig doesn't. > This isn't safety… This is “we didn't fi…

> It is true that if you use unsafe Zig, i.e. turn off safety for a whole program or some sections of it, you lose the guarantees that safe Zig gives you, and unsafe Zig is indeed not safe Their is no such things as unsafe and safe Zig. All Zig is unsafe, but you can add additional runtime checks (disabled by default in optimized builds) that will slow down your program when used. Using a specific allocator to detect…

> Their is no such things as unsafe and safe Zig. All Zig is unsafe, but you can add additional runtime checks

Zig is meant to ultimately give you full memory safety, that you can selectively turn off. In addition, there are specific unsafe operations -- clearly marked -- such as casting an integer to a pointer or other non-typesafe casts.

A code unit with safety checks on and without unsafe operations is what I call "safe Zig."

> And without it your code isn't memory-safe.

This is simply not true. Perhaps you mean that you don't have a guarantee that your code is memory-safe, but that's not the same thing.

Our goal is not to write in a language with certain guarantees but to write programs with certain properties, say, without buffer overflows. One way of achieving such a program is to write it in a language that guarantees no such error can happen. Another is to write it in a language that guarantees no such error can happen in development, do some testing, and then remove the guarantees. In the second case it is true that our confidence in the lack of such errors is lower than the first, but in each case it is not 100%, and because the static guarantees are costly, it is possible that the second approach is even more effective at getting to more correct programs overall. They're both common ways for achieving the same goal.

As someone who works with formal methods, we do these tradeoffs in formal verification all the time. It is simple false that sound guarantees are always the best way to correctness -- it would be if they were free, but they're not.

Once you realise that the goal is achieving some desired level of confidence (which is never 100%, as that cannot exist in a physical system anyway) about overall program correctness -- which includes both "safety" and functional properties, each further divided into degrees of severity -- you see that there is no obvious way with the best effectiveness at achieving that goal.

> If you never explicitly test the value “1337” during you debug session, you won't trigger the UB and you won't know it's here

But here, again, you are looking at something in isolation. Because Zig is a simple language, the chances of such paths existing without you noticing are lower; also, because the language is simpler it is easier to write concolic testers that would automatically detect this.

In fact, if such a "rare path" exists in a complex language that causes some functional bug -- ultimately, we don't care what bug breaks our program or leaves it open to security vulnerabilities -- there's a smaller chance that it will be discovered. Which is exactly what I mean by soundness coming at a cost. It guarantees the lack of certain bugs, but because it complicates the language, it can make other bugs more costly to detect.

Re: Interview with Zig language creator Andrew Kelley [video]

#170
post #60

Earlier quoted context omitted.

> Sometimes you do not want to be burdened by the limitations of a "high-level" language. I see very few people suffering from such burdens, but a great many suffering from its exact opposite: using a low- or mid-level language to write hundreds of lines where ten lines in a higher-level language would suffice and be more easily verified as correct.

> I see very few people suffering from such burdens, but a great many suffering from its exact opposite: using a low- or mid-level language to write hundreds of lines where ten lines in a higher-level language would suffice and be more easily verified as correct. I see a huge load of people suffering from those burdens. Higher-level languages tend to be less efficient and less optimal. Yes, they take a burden from th…

Thanks for writing this.
Post reply on HN