frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

Open in hackernews

Zig's New Writer

https://www.openmymind.net/Zigs-New-Writer/
76•Bogdanp•1d ago

Comments

mishafb•1d ago
I agree on the last point of the lack of composition here.

While it's true that writers need to be aware of buffering to make use of fancy syscalls, implementing that should be an option, but not a requirement.

Naively this would mean implementing one of two APIs in an interface, which ruins the direct peformance. So I see why the choice was made, but I still hope for something better.

It's probably not possible with zig's current capabilities, but I would ideally like to see a solution that:

- Allows implementations to know at comptime what the interface actually implements and optimize for that (is buffering supported? Can you get access to the buffer inplace for zero copy?).

- For the generic version (which is in the vtable), choose one of the methods and wrap it (at comptime).

There's so many directions to take Zig into (more types? more metaprogramming? closer to metal?) so it's always interesting to see new developments!

biggerben•6h ago
I wonder if making this change will improve design of buffering across IO implementers because buffering needs consideration upfront, rather than treatment as some feature bolted on the side?

It’s a good sacrifice if the redesign, whilst being more complicated, is avoiding an oversimplified abstraction which end up restricting optimisation opportunities.

messe•4h ago
> While it's true that writers need to be aware of buffering to make use of fancy syscalls, implementing that should be an option, but not a requirement.

Buffering is implemented and handled in the vtable struct itself, the writers (implentations of the interface) themselves don't actually have to know or care about it other than passing through the user-provided buffer when initializing the vtable.

If you don't want buffering, you can pass a zero-length buffer upon creation, and it'll get optimized out. This optimization doesn't require devirtualization because the buffering happens before any virtual function calls.

amluto•4h ago
From my personal experience, buffered and unbuffered writers are different enough that I think it’s a bit of a mistake to make them indistinguishable to the type system. An unbuffered writer sends the data out of process immediately. A buffered writer usually doesn’t, so sleeping after a write (or just doing something else and not writing more for a while) will delay the write indefinitely. An unbuffered write does not do this.

This means that plenty of algorithms are correct with unbuffered writers and are incorrect with buffered writers. I’ve been bitten by this and diagnosed bugs caused by this multiple times.

Meanwhile an unbuffered writer has abysmal performance if you write a byte at a time.

I’d rather see an interface (trait, abstract class, whatever the language calls it) for a generic writer, with appropriate warnings that you probably don’t want to use it unless you take specific action to address its shortcomings, and subtypes for buffered and unbuffered writers.

And there could be a conditional buffering wrapper that temporarily adds buffering to a generic writer and is zero-cost if applied to an already buffered writer. A language with enforced borrowing semantics like Rust could make this very hard to misuse. But even Python could do it decently well, e.g.:

    w: MaybeBufferedByteWriter
    with io.LocalBuffer(w) as bufwriter:
        do stuff with bufwriter
donatj•2h ago
I absolutely agree, and would like to add I feel like the ergonomics of the new interface are just very awkward and almost leaky.

Buffered and unbuffered IO should just be entirely separately things, and separate interfaces. Then as you mention the standard library can provide an adapter in at least one direction, maybe both.

This seems like a blunder to me.

josephg•1h ago
> This means that plenty of algorithms are correct with unbuffered writers and are incorrect with buffered writers. I’ve been bitten by this and diagnosed bugs caused by this multiple times.

But write() on POSIX is also a buffered API. Until your program calls fsync / fdatasync, linux isn't required to actually flush anything to the underlying storage medium. And even then, many consumer storage devices will lie and return from fsync immediately before data has actually been flushed.

All the OSes that I know of will eagerly write data instead of waiting for fsync, but there's no guarantee the data will be persisted by the time your write() call returns. It usually isn't. If you're relying on write() to durably flush data to disk, you've probably got correctness / data corruption bugs lurking in your code that will show up if power goes out at the wrong time.

mmastrac•2h ago
It's an interesting choice, but every writer now needs to handle:

1) vectored i/o (array of arrays, lots of fun for cache lines)

2) buffering

3) a splat optimization for compression? (skipped over in this post, but mentioned in an earlier one)

I'm skeptical here, but I guess we will see if adding this overhead on all I/O is a win. Devirtualization helps _sometimes_ but when you've got larger systems it's entirely possible you've got sync and async I/O in the same optimization space and lose out on optimization opportunities.

In practice, I/O stacks tend to consist of a lot of composition, and in many cases, leak a lot of abstractions. Buffering is one part, corking/backpressure is another (neither of which is handled here, but I might be mistaken). In some cases, you've got meaningful framing on streams that needs to be maintained (or decorated with metadata).

If it works out, I suppose this will be a new I/O paradigm. In fairness, nobody has _really_ solved I/O yet, so maybe a brave new swing is what we need.

wasmperson•1h ago
I'm not usually in the "defending C++" camp, but when I see this:

  pub const File = struct {
  
    pub fn writer(self: *File, buffer: []u8) Writer{
      return .{
        .file = self,
        .interface = std.Io.Writer{
          .buffer = buffer,
          .vtable = .{.drain = Writer.drain},
        }
      };
    }
  
    pub const Writer = struct {
      file: *File,
      interface: std.Io.Writer,
      // this has a bunch of other fields
  
      fn drain(io_w: *Writer, data: []const []const u8, splat: usize) !usize {
        const self: *Writer = @fieldParentPtr("interface", io_w);
        // ....
      }
    }
  }
...I can't help but think of this:

  struct FileWriter: public Writer {
      File *file;
      // this has a bunch of other fields
  
      FileWriter(File *self, span<char> buffer)
          : Writer(buffer), file(self) {}
  
      size_t drain(span<span<char const> const> data, size_t splat) override {
        // ....
      }
  };
Writing code to build a vtable and having it implicitly run at compile time is pretty neat, though!

Fstrings.wtf

https://fstrings.wtf/
103•darkamaul•2h ago•28 comments

I avoid using LLMs as a publisher and writer

https://lifehacky.net/prompt-0b953c089b44
35•tombarys•2h ago•7 comments

My Self-Hosting Setup

https://codecaptured.com/blog/my-ultimate-self-hosting-setup/
330•mirdaki•10h ago•125 comments

A 14kb page can load much faster than a 15kb page (2022)

https://endtimes.dev/why-your-website-should-be-under-14kb-in-size/
276•truxs•4h ago•178 comments

Pimping My Casio: Part Deux

https://blog.jgc.org/2025/07/pimping-my-casio-part-deux.html
70•r4um•5h ago•19 comments

Valve confirms credit card companies pressured it to delist certain adult games

https://www.pcgamer.com/software/platforms/valve-confirms-credit-card-companies-pressured-it-to-delist-certain-adult-games-from-steam/
607•freedomben•21h ago•592 comments

Felix Baumgartner, who jumped from stratosphere, dies in Italy

https://www.theinternational.at/felix-baumgartner-who-jumped-from-stratosphere-dies-in-italy/
34•signa11•2h ago•15 comments

Piramidal (YC W24) Is Hiring a Full Stack Engineer

https://www.ycombinator.com/companies/piramidal/jobs/JfeI3uE-full-stack-engineer
1•dsacellarius•1h ago

Linux and Secure Boot certificate expiration

https://lwn.net/SubscriberLink/1029767/43b62a7a7408c2a9/
5•todsacerdoti•4h ago•2 comments

Hyatt Hotels are using algorithmic Rest “smoking detectors”

https://twitter.com/_ZachGriff/status/1945959030851035223
149•RebeccaTheDev•9h ago•70 comments

YouTube No Translation

https://addons.mozilla.org/en-US/firefox/addon/youtube-no-translation/
57•thefox•5h ago•26 comments

GPT-5-reasoning alpha found in the wild

https://twitter.com/btibor91/status/1946532308896628748
33•dejavucoder•1h ago•31 comments

How to write Rust in the Linux kernel: part 3

https://lwn.net/SubscriberLink/1026694/3413f4b43c862629/
209•chmaynard•14h ago•5 comments

OpenAI claims Gold-medal performance at IMO 2025

https://twitter.com/alexwei_/status/1946477742855532918
38•Davidzheng•3h ago•51 comments

Advertising without signal: The rise of the grifter equilibrium

https://www.gojiberries.io/advertising-without-signal-whe-amazon-ads-confuse-more-than-they-clarify/
99•neehao•10h ago•44 comments

Astronomers use colors of trans-Neptunian objects to track ancient stellar flyby

https://phys.org/news/2025-07-astronomers-trans-neptunian-track-ancient.html
4•bikenaga•2d ago•0 comments

Asynchrony is not concurrency

https://kristoff.it/blog/asynchrony-is-not-concurrency/
261•kristoff_it•17h ago•185 comments

Meta says it won’t sign Europe AI agreement, calling it an overreach

https://www.cnbc.com/2025/07/18/meta-europe-ai-code.html
258•rntn•19h ago•331 comments

An exponential improvement for Ramsey lower bounds

https://arxiv.org/abs/2507.12926
8•IdealeZahlen•3h ago•0 comments

C# Language Design Meeting for June 30th, 2025

https://github.com/dotnet/csharplang/blob/main/meetings/2025/LDM-2025-06-30.md
23•jasonthorsness•3d ago•16 comments

Every part on a bicycle is safety critical

https://escapecollective.com/threaded-43-every-part-on-a-bike-is-safety-critical/
28•spooky_deep•5h ago•18 comments

Bun adds pnpm-style isolated installation mode

https://github.com/oven-sh/bun/pull/20440
85•nateb2022•12h ago•14 comments

A CarFax for Used PCs: Hewlett Packard wants to give old laptops new life

https://spectrum.ieee.org/carfax-used-pcs
10•miles•3d ago•6 comments

Debcraft – Easiest way to modify and build Debian packages

https://optimizedbyotto.com/post/debcraft-easy-debian-packaging/
65•pabs3•12h ago•16 comments

Broadcom to discontinue free Bitnami Helm charts

https://github.com/bitnami/charts/issues/35164
183•mmoogle•17h ago•95 comments

Mr Browser – Macintosh Repository file downloader that runs directly on 68k Macs

https://www.macintoshrepository.org/44146-mr-browser
70•zdw•12h ago•15 comments

When to make LODs: Understanding model costs

https://medium.com/@jasonbooth_86226/when-to-make-lods-c3109c35b802
15•azeemba•2d ago•4 comments

Silence Is a Commons by Ivan Illich (1983)

http://www.davidtinapple.com/illich/1983_silence_commons.html
163•entaloneralie•15h ago•35 comments

Zig's New Writer

https://www.openmymind.net/Zigs-New-Writer/
76•Bogdanp•1d ago•8 comments

C++: Zero-cost static initialization

https://cofault.com/zero-cost-static.html
65•oecumena•4d ago•24 comments