Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Defer sounds like a nice improvement over old old languages, but Java's try-with-resources is one of the nicer ways of handling resource cleanup I've seen in a "mainstream" language, it's fairly neat and conceptually similar to some stuff I've seen done with lisp macros or Ruby blocks. It seems like defer is still lacking compared to this.


With defer it's developer's responsibility to free resources in right order, when one depends on another. Maybe something like this in Zig would be better:

  try std.fs.cwd().openFile(path, .{}) |file| : file.close()
  {
    // ... code ...
    // file.close() is called at the end
  }


defer in Zig is per-scope, so

    {
        var file = try std.fs.cwd().openFile(path, .{});
        defer file.close();

        // ... code ...
        // file.close() is executed here
    }
would work just fine.


Yes, but look at the example in the blog post of this thread- "stat" depends on "file", "file" depends on "path". You can call defer in any order in your code, the language syntactically doesn't enforce you to call defer right after resource acquisition. "try-with-resources" in Java (or "using" in c#) will always call "finalizers" in order opposite to how resources where created. Following the syntax I inveted above, for someone used to Java it would be easier to read than to think how defers are called:

  try std.fmt.allocPrint(allocator, "problems/{}", .{ id }) |path| : allocator.free(path) {
    try std.fs.cwd().openFile(path, .{}) |file| : file.close() {
      try file.stat() |stat| {
        try allocator.alloc(u8, stat.size) |contents| : allocator.free(contents) {
          // do something with 'contents'
        }
      }
    }
  }
In Zig you can write this, and mess everything up:

  const path = try std.fmt.allocPrint(allocator, "problems/{}", .{ id });
  var file = try std.fs.cwd().openFile(path, .{});
  const stat = try file.stat();
  var contents = try allocator.alloc(u8, stat.size);
  defer allocator.free(contents);
  defer file.close();
  defer allocator.free(path);


That's what errdefer is for.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: