Zig NEWS

guidorice
guidorice

Posted on

Zig's var and const for JavaScript devs

Coming from javascript and typescript, you might see Zig's var and const and have a concept of what that means. var is short for variable, const is short for constant. Variable vs Constant: easy-peasy. Wait not so fast! This post will help you test out those concepts, and get comfy with Zig's var and const.

Allows changing values

zig var zig const js var js let js const
✔️ ✔️ ✔️ 😬

Let's step through that table with some examples:

zig var

var x: u8 = 0;
x += 255;
std.log.info("{}", .{ x });
// info: 255
Enter fullscreen mode Exit fullscreen mode

Yep, we can change var's value.

zig const

const x: u8 = 0;
x += 255;
// error: cannot assign to constant
Enter fullscreen mode Exit fullscreen mode

No surprises here.

js var and let

var x = 0;
x += 255;
console.log(x);
// 255

let y = 0;
y += 255;
console.log(y);
// 255
Enter fullscreen mode Exit fullscreen mode

Both allow changing of value. Hence "variable". All is right with the world.

js const

const x = 0;
x += 255;
// TypeError: Assignment to constant variable.
Enter fullscreen mode Exit fullscreen mode

Javascript prevents assignment to const. What about changing a value of a const (like, of an object?)

const foo = { id: 42, color: 'blue', health: 8 };
foo.health += 100;
console.log(foo);
// { id: 42, color: 'blue', health: 108 }
Enter fullscreen mode Exit fullscreen mode

Javascript does not prevent you changing the value of a const ! Unless you use Object.freeze() which is let's face it: pretty obscure, in practice.

Javascript's const isn't really weak, it's just that every non-primitive variable is essentially a pointer (DoctorQuantum)

Here we could go down the rabbit hole of javascript memory model vs zig memory model, but this is just a #learning post (and I'm not up to speed on all that). Let's just keep it "in practice".

Try the same foo example in zig:

const std = @import("std");
const FooMonster = struct {
    id: usize,
    color: []const u8,
    health: u8,
};
pub fn main() void {   
    const foo = FooMonster{ .id = 42, .color = "blue", .health = 8 };
    foo.health += 100;
    // error: cannot assign to constant
    std.log.info("{}", .{ foo });
}
Enter fullscreen mode Exit fullscreen mode

Change foo to be var, and then you can assign a new health value.

Scope

Zig variables may be container level, static local, thread local, or just local. Blocks are used to scope variable declarations.

zig var zig const js var js let js const
block block function 😩 block block

There is no equivalent of Js var scoping in Zig. Js let was invented because function scoping was, well, not the best in practice.

Redeclaring

Js let does not allow redeclaring. Shadowing and hence, re-declaration, are not a thing in Zig.

Further Study

  • Zig has some different rules than JavaScript about initialization of variables.
  • Pointers have their own "const-ness".
  • Zig adds a new concept comptime! The value of variable must be known or computable at compile time.

Learn more in the Language Reference.

Parting thoughts

It is generally preferable to use const rather than var when declaring a variable. This causes less work for both humans and computers to do when reading code, and creates more optimization opportunities. (Zig language reference)

Oldest comments (2)

Collapse
 
kristoff profile image
Loris Cro

Thanks for the writeup!

Pointers have their own "const-ness".

Yep, that's probably worthy of its own blog post :^)

Collapse
 
guidorice profile image
guidorice

Author here: in TypeScript we got "const assertions" typescriptlang.org/docs/handbook/r...
Which are kind of related to the examples above.