News for hackers. Stuff that matters.
Re:Rust: A Critical Retrospective by flohofwoe on Thursday May 19, 2022 @10:40AM (#31435277)
An optional is just a '?' before the type:

For instance a function which returns an optional pointer to a 'Bla':

    fn make_bla() ?*Bla {
        // this would either return a valid *Bla, or null
    }
A null pointer can't be used accidentally, it must be unwrapped first, and in Zig this is implemented as language syntax, for instance you can unwrap with an if:

    if (make_bla()) |bla| {
        // bla is now the unwrapped valid pointer
    } else {
        // make_bla() returned null
    }
...or with an orelse:

    const bla = make_bla() orelse { return error.InvalidBla };
...or if you know for sure that bla should be valid, and otherwise want a panic:

    const bla = make_bla().?;
...error handling with error unions has similar syntax sugar.

It's probably not perfect, but I feel that for real-world code, working with optionals and errors in Zig leads to more readable code on average than Rust, while providing the same set of features.

Re:Rust: A Critical Retrospective by veber-alex on Thursday May 19, 2022 @11:23AM (#31435895)
I don't see how that is all that different from Rust.

The main difference I see is that in Rust it will also work with your own custom types, not just optional.

  fn make_bla() -> Option<Bla> {
    // this either returns a valid Bla, or None
  }

  if let Some(bla) = make_bla() {
    // bla is now the unwrapped valid type
  } else {
    // make_bla() returned None
  }
..or with the '?' operator (early return)

  let bla = make_bla().ok_or(InvalidBla)?;
..or with let_else (nightly only but should be stable Soon(tm))

  let Some(bla) = make_bla() else { return Err(InvalidBla) }
..or panic on None

  let bla = make_bla().unwrap();
Re:Rust: A Critical Retrospective by wtetzner on Thursday May 19, 2022 @10:23PM (#31442641)
How does Zig represent Option<Option<i32>>? Would it be something like this?

    ??i32
Re:Rust: A Critical Retrospective by flohofwoe on Friday May 20, 2022 @03:30AM (#31444372)
I had to try it out first, but yep, that's how it works:

    const assert = @import("std").debug.assert;

    fn get12() i32 {
        const opt_opt_val: ??i32 = 12;
        const val = opt_opt_val.?.?;
        comptime assert(val == 12);
        return val;
    }
[https://www.godbolt.org/z/oncd5shvP]