Skip to content

Instantly share code, notes, and snippets.

@lukebayes
Last active June 17, 2021 16:00
Show Gist options
  • Save lukebayes/8bc953c2286f376a21ffc5f6365b3ba0 to your computer and use it in GitHub Desktop.
Save lukebayes/8bc953c2286f376a21ffc5f6365b3ba0 to your computer and use it in GitHub Desktop.
How to work with heterogenous Tuple types in Zig?
const std = @import("std");
const print = std.debug.print;
// The dreaded, "unable to evaluate constant expression"
//
// I'm having a difficult time understanding when the zig compiler transitions
// my code execution from comptime to runtime and I'm pretty sure this is the
// root cause of my struggles here.
//
// I do understand that I may be looking for more dynamism than Zig is
// prepared to provide.
//
// For clarity, I'm actually attempting to construct large and wide trees of
// homogeneous entities that compose heterogeneous collections of attributes
// without allocating massive blocks of memory for every single potential
// attribute.
//
// Really, my question is, is something like the following even syntactically
// possible in Zig?
//
// const elem = div(.{
// name("abcd"),
// width(800),
// height(600),
// children(.{
// div(.{ name("efgh") }),
// div(.{ name("ijkl") }),
// div(.{ name("mnop") }),
// }),
// });
//
// There are a collection of questions below, and any code that doesn't compile
// in zig version 0.8.0 has been commented out.
//
// Ideally, this code could be uncommented, repaired and compiled such that the
// the commented out test will pass.
//
// Any tips appreciated.
const FakeParamName = enum {
Aye,
Bee,
Cee,
};
fn FakeParam(comptime T: type) type {
return struct {
name: FakeParamName,
value: T,
};
}
const FakeUintParam = FakeParam(u32);
const FakeStringParam = FakeParam([]const u8);
const FakeBoolParam = FakeParam(bool);
pub fn Aye(value: u32) FakeUintParam {
return .{ .name = FakeParamName.Aye, .value = value };
}
pub fn Bee(value: []const u8) FakeStringParam {
return .{ .name = FakeParamName.Bee, .value = value };
}
pub fn Cee(value: bool) FakeBoolParam {
return .{ .name = FakeParamName.Cee, .value = value };
}
// QUESTION: How does one set the type of a tuple?
// const stored_params: FakeParam(type) = undefined;
// I'd like to store the values sent to this function
// QUESTION: How does one store an anytype?
fn storeParams(params: anytype) void {
print("params: {any}\n", .{params});
// This isn't it:
// stored_params = params;
var i: usize = 0;
while (i < params.len) {
// QUESTION: Why doesn't this work?
// const name = params[i].name;
// QUESTION: Why doesn't this work?
// print("param found: {any}\n", .{params[i].name});
i += 1;
}
}
// Return the .value for the first param whose name matches the provided name.
// Q3: How does one get a value of an unknown type?
// fn getParamByName(name: FakeParamName) ?anytype {
// var i: usize = 0;
// while (i < stored_params.len) {
// if (stored_params[i].name == name) {
// return stored_params[i].value;
// }
// }
//
// return null;
// }
test "How to store and load tuple values?" {
storeParams(.{
Aye(42),
Bee("bee"),
Cee(false),
});
// const aye = getParamByName(FakeParamName.Aye);
// try expectEqual(aye, 42);
// const bee = getParamByName(FakeParamName.Bee);
// try expectEqualStrings(bee, "bee");
// const cee = getParamByName(FakeParamName.Cee);
// try expectEqual(cee, false);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment