Hacker News new | ask | show | jobs
by stop50 296 days ago
I have never understood libraries or imterfaces that want me to allocate buffers for their type. I can't parse them (no need for the lib then) or write to them (would probably break the exchange).

The weird interface of go is probably due the fact that some interfaces can be used to extemd the writer like the hijacker interface (ResponseWriter.(http.Hijacker)) and the request object is used multiple times with different middlewares interacting with it. In short: request does not need to be extended, but the response can be an websocket, an wrapped tcp connection or something else.

3 comments

> I have never understood libraries or imterfaces that want me to allocate buffers for their type.

That doesn't seem that odd to me. It's a trade off: more flexibility, but more manual work. Maybe I have a buffer that I've allocated that I'm not using anymore (say I have a buffer pool) and want to use it again. If the type allocates its own behind the scenes, I can't do that. Or maybe I'm working in an environment where I need to statically allocate all of my resources up-front, and can't allocate later.

The big downside is that if 90% of people are just going to allocate a buffer and pass it in, it sucks that 90% of people need to do more work and understand more minutiae when only 10% of the people actually need to. The holy grail is to give lots of flexibility, but make the simple/common case easy.

A simple improvement to this interface might be to allow the caller to pass a zero-length buffer (or Zig's version of null), and then the type will allocate its own buffer. Of course, there's still a documentation burden so people know they can do that. Another option could be to have second constructor function that takes no buffer arguments at all, which allocates the buffers and passes them to the fully-flexible constructor function.

> If the type allocates its own behind the scenes, I can't do that.

Isn't that the reason why Zig passes around allocators everywhere? If you're using a buffer pool, you should probably be handing out some kind of buffer pool allocator.

Requiring all allocation to have happened before execution is still a good reason to pass buffers around, but I feel like the other situations you describe can be solved by just passing the right allocators.

It's just a different convention like radians and degrees.

You can lift/unlift in or out of arbitrary IO, in some languages one direction is called a mock, in other languages the opposite is called unsafeFoo.

Andrew Kelley independently rediscovered on a live stream 30 years of the best minds in Haskell writing papers.

So the future is Zig. He got there first.

Only if use after free story actually gets fixed, and not by repurposing what has already existed in the C and C++ ecosystems for the last 30 years, like PurifyPlus or VC++ debug allocator.
If you mean running clang-tidy as a separate build step or ASAN in a different category than other soundness checks?

Compute is getting tight, lots of trends, the age of C++ is winding down gracefully. The age of Zig is emerging delibetately, and the stuff in the middle will end up in the same historical trash bin as everything else in the Altman Era: the misfortunes of losing sight of the technology.

I mean those and other ones, we already have enough unsafe languages as it is.

The age of C++ is going great, despite all its warts and unsafety, thanks to compiler frameworks like GCC and LLVM, games industry, GPGPU and Khronos APIs.

Even if C++ loses everywhere else, it has enough industry mindshare to keep being relevant.

Same applies to C, in the context of UNIX clones, POSIX, Khronos, embedded.

Being like Modula-2 or Object Pascal in safety, in C like syntax, isn't enough.

> we already have enough unsafe languages as it is

By that logic, we definitely have enough safe languages as it is, as there are many more. But this safe/unsafe dichotomy is silly, and is coloured by languages that are unsafe in some particular ways.

1. Memory safety is important because memory-safety violations are a common cause of dangerous security vulnerabilities. But once you remove out-of-bounds access, as Zig does, memory safety doesn't even make it to the top 5: https://cwe.mitre.org/top25/archive/2024/2024_cwe_top25.html I.e. the same logic that says we should focus on safety would lead us to conclude we should focus on something else.

2. Memory safety has a cost. To get it, you have to give up something else (there could even be a cost to correctness). That means that you have to consider what you're getting and what you're losing in the context of the domain you're targeting, which is not the same for all languages. C++, with its "zero-cost abstractions", believed it could be everything for everyone. That turned out not to be the case at all, and Zig is a very different language, with different goals, than C++ originally had.

Given Zig's safety guarantees (which are stronger than C++'s), and given its goals (which are different from C++'s), the question should be what should we be willing to give up to gain safety from use-after-free given the language's goals. Would more safety be better if it cost nothing? Of course, but that's not an option. Even Java and Rust could prevent many more dangerous bugs - including those that are higher risk than use-after-free - if they had more facilities like those of ATS or Idris. But they don't because their designers think that the gains wouldn't be worth the cost.

If you don't say what Zig programmers should give up to gain more safety, saying "all new languages should be memory-safe" is about as meaningful as saying we should write fewer bugs. That's a nice sentiment, but how and at what cost?

> there could even be a cost to correctness

Notice that this cost, which proponents of Zig scoff at just like C++ programmers before them, is in fact the price of admission. "OK, we're not correct but..." is actually the end of the conversation. Everybody can already do "Not correct", we had "Not correct" without a program, so all effort expended on a program was wasted unless you're correct. Correctness isn't optional.

We actually already have enough safe languages as well.

I am a firm beliver in the vision of Xerox PARC for computing, and think the only reason we aren't yet there are politics, lack of funding from management for doing the right thing pushing them into the market, always looking to shareholders and the next quarter, and naturally programming language religion.

We were already on the right direction with languages like Modula-3 and Active Oberon, following up on Cedar influences, unfortunately that isn't how the industry goes.

> Given Zig's safety guarantees (which are stronger than C++'s), and given its goals (which are different from C++'s), the question should be what should we be willing to give up to gain safety from use-after-free given the language's goals. Would more safety be better if it cost nothing?

The problem with this statement is that without a memory safety invariant your code doesn't compose. Some code might assume no UAF and other parts could and you'd have a mismatch. Just like borrow checker is viral, so is the unsafety.

> If you don't say what Zig programmers should give up to gain more safety, saying "all new languages should be memory-safe" is about as meaningful as saying we should write fewer bugs.

The goal of all engineering disciplines, including software, should be a minimization of errors and defects.

Here is how engineering in any other non-computer science field takes place. You build something. See where it breaks; try to build it again given time and budget constraints. Eventually you discover certain laws and rules. You learn the rules and commit them to a shared repository of knowledge. You work hard to codify those laws and rules into your tools and practice (via actual government laws). Furthermore, you try to build something again, with all the previous rules, tools, and accumulated knowledge.

How it works in tech. You build something. See where it breaks, say that whoever built it was a cream-for-brain moron and you can do it better and cheaper. Completely forget what you learned building the previous iteration. See where it breaks. Blame the tools for failure; remove any forms of safety. Project cancelled due to excessive deaths. Bemoan the lack of mental power in newer hires or lack of mental swiftness in older hires. Go to step 1.

You'll notice a stark contrast between Engineering and Computer Tech. Computer tech is pop culture. It's a place where people wage wars about whether lang X or lang Y is better. How many times did programming trend go from static to dynamically typed? How many times did programming learned a valuable lesson, only for everyone to forget it, until decades later another language resurrected it?

Ideally, each successive language would bring us closer and closer to minimizing defects, with more (types of) safety and better guarantees. Is Rust a huge leap compared to Idris? No, it's better than Ada at memory safety that's for sure.

But it's managed to capture a lot of attention, and it is a much stricter language than many others. It's a step towards ideal. And how do programmers react to it? With disgust and a desire for less safety.

Sigh. I guess we deserve all the ridicule we can get.

Haskell makes guarantees. Modern C++ makes predictions to within a quantifiable epsilon.

Rust makes false promises in practical situations. It invented a notion of safety that is neither well posed, nor particularly useful, nor compatible with ergonomic and efficient computing.

It's speciality is marketing and we already know the bounding box on its impact or relevance. "Vibe coding" will be a more colorful and better remembered mile marker of this lousy decade in computers than Rust, which will be an obscurity in an appendix in 100 years.

There is almost nothing accurate about this comment.

"Makes predictions to within a quantifiable epsilon"? What in the world do you mean? The industry experience with C++ is that it is extremely difficult (i.e., expensive) to get right, and C++20 or newer does not change anything about that. Whatever "epsilon" you are talking about here surely has to be very large for a number bearing that sobriquet.

As for the mindless anti-Rust slander... I'm not sure it's worth addressing, because it reflects a complete lack of the faintest idea about what it actually does, or what problem it solves. Let me just say there's a reason the Rust community is rife with highly competent C++ refugees.

> "Vibe coding" will be a more colorful and better remembered mile marker of this lousy decade in computers than Rust, which will be an obscurity in an appendix in 100 years.

I doubt it.

I'm teaching a course on C this fall. As textbook I've chosen "Modern C" by Jens Gustedt (updated for C23).

I'm asked by students "Why don't you choose K&R like everyone else?"

And while the book is from 1978 (ANSI C edition in 1988), and something I've read joyously more than once, I'm reminded of how decades of C programmers have been doing things "the old way" because that's how they're taught. As a result, the world is made of old C programs.

With this momentum of religiously rewriting things in Rust we see in the last few years (how many other languages have rewritten OpenSSL and the GNU coreutils?), the amount of things we depend on that was incidentally rewritten in Rust grows significantly.

Hopefully people won't be writing Rust in 100 years. Since 100 years ago mathematicians were programming mechanical calculators and analog computers, and today kids are making games. But I bet you a whole lot of infrastructure still runs Rust.

In fact, anything that is convenient to Vibe code in the coming years will drown out other languages by volume. Rust ain't so bad for vibe coding.

I hope in 100 years we're not using any of the languages available today. I do like Rust, and use it whenever it's appropriate, but it has its warts and sharp edges. Hopefully we'll come up with something better in the next century.
> Rust makes false promises in practical situations. It invented a notion of safety that is neither well posed, nor particularly useful, nor compatible with ergonomic and efficient computing.

Please stop. Rust's promise is very simple. You get safety without the tracing GC. It also gives you tools to implement your own safe abstraction on top of unsafe, but you are mostly on your own (miri, asan, and ubsan can still be used).

Neither Rust nor Ada nor Lean nor Haskell can guarantee there are no errors in their implementations.

Similarly, none of the listed languages can even try to show that a bad actor can't write bad code or design bad hardware in a way that maintains their promises. If you need that, you need to invent the Omniscient Oracle, not a program.

I hate this oft repeated Nirvana fallacy. Yes, Rust is offering you a car with seatbelts and airbags. It is not offering a car that guarantees immortality in the event of a universe collapse.

> The age of Zig is emerging delibetately

Pet projects are nice, but slow down with the copium intake.

> So the future is Zig. He got there first.

The future is many things, but a love letter to C is definitely not it.

Zig is cute and a fun hobby project that might see above average success for a hobby project. But that's about it. It doesn't address the problems people actually have with C++, not like Rust or Swift do, and it certainly isn't going to attract any attention from the Java, JavaScript, C#, Python, etc... of the world.

Zig is not a hobby project.

> It doesn't address the problems people actually have with C++, not like Rust or Swift do

Speak for yourself. Zig addresses pretty much all of my problems with C++:

- terrible compile times - overly complex and still underpowered template/meta programming - fragmented/ancient build tools - actually good enums/tagged unions - exceptions - outdated OOP baggage

I don’t actually mind C++ that much, but Zig checks pretty much all of my boxes. Rust/swift check some of these but not all and add a few of their own.

> and it certainly isn't going to attract any attention from the Java, JavaScript, C#, Python, etc... of the world.

Yeah of course. Zig isn’t trying to be a max ergonomics scripting language…

Isn’t the whole point of an external buffer that the function won’t need to allocate?