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

(Non-user of Zig here.)

    // tea.zig
    full: bool = true,
    const Self = @This();
    
    pub fn drink(self: *Self) void {
      self.full = false;
    }

    // other.zig
    const Tea = @import("tea.zig");
This example seemed to stop just short of the really interesting bit: what if other.zig called Tea.drink()? Would it set Tea.full to false? Maybe this is obvious to Zig users, but coming from C++, that would be a violation of const correctness.

In C++ (thinking of classes rather than files), you wouldn't be able to call the drink method of a const object because it's not marked as a const method. Or, if it was marked as a const method, you wouldn't be able to modify full from in drink. You could get around this by marking full as mutable, which means you're going to deliberately violate const correctnees, but at least you have to be explicit about it. (In theory mutable is meant for things like caches that don't affect the visible behaviour of the class.)



> what if other.zig called Tea.drink()?

To be clear: you would first need to create an instance of `Tea`.

   var t: Tea = .{};
   t.drink(); // will work and set t.full to false
If instead we declared `t` as `const`, then yes the call to `drink` would not have been possible.

`const Self = @This();` just binds the top-level struct type definition to a name, which then allows you to refer to it in other plances. Nothing more than that.


Ah that does make sense, thanks.

Is it possible to mark a method const in Zig, like in C++? I guess you set the type of the self parameter to const *Self or similar?


Yep!

   fn foo(self: Self) void {}
   fn bar(self: *const Self) void {}
   fn baz(self: *Self) void {}
In this example, `foo` and `bar` cannot modify `self`, while `baz` can. In the case of `foo`, `self` is passed in by value, but since function arguments are immutable in Zig, it cannot be modified (the compiler might still opt for pass-by-reference under the hood, but the semantics don't change).

In the case of `bar` we are explicitly asking for a constant pointer, as you mentioned.


I spent a lot of this weekend learning Zig, and this was the most surprising this for me. foo, bar, and baz are all called the same way (as thing.foo() or thing.baz()), but depending on the type signature, the compiler can figure out whether you want a mutable or immutable reference to the object.


It’s pretty common for languages in the field e.g. C++ (const versus non-const methods), Rust (value, unique reference, shared reference, deref), and even Go (value v pointer, delegation).

The “method syntax” is pretty much just a convenience, so why not also handle that after all?


This is common behavior for languages. D adds another wrinkle to it - a reference can be mutable, const, or immutable.

mutable: can modify it

const: cannot modify it through the reference, but other mutable references can still modify it

immutable: nobody can modify it

The 'immutable' is great for writing threaded code, as no synchronization is necessary.


The type of Tea is 'type', not Tea. Unlike in C++, types are values in Zig, so it would be like calling Tea::drink() in C++.

You need an instance of Tea in order to call drink, and if it's const it won't compile because drink takes type *Tea, not *const Tea.


Interesting, thanks. In that case, what if `Tea` was not const? Could I assign a different type to it? What would the static type of an instance of Tea be, if its runtime value could be two incompatible types?


1. You can use a type variable as a normal one, as long as you do it at compile time (a variable of type type is required to be comptime). You can use a TypeInfo at runtime if you like though.

2. The type system is deep enough to describe the type of values, but not the type of types. That's what higher kinded types are for, and for better or for worse that's not part of zig. Also, type variables can only exist at compile time, so there is no runtime value.


thanks!




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

Search: