Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

comptime struct fields #3677

Closed
andrewrk opened this issue Nov 13, 2019 · 6 comments
Closed

comptime struct fields #3677

andrewrk opened this issue Nov 13, 2019 · 6 comments
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@andrewrk
Copy link
Member

const std = @import("std");

const Foo = struct {
    a: i32,
    comptime b: i32 = 1234,
};

test "example" {
    var foo: Foo = undefined;
    comptime std.debug.assert(foo.b == 1234);
}

A comptime struct field requires a default initialization value. Loads from a comptime struct field result in a comptime value of the default initialization value. Stores to a comptime struct field assert that the stored value is the default initialization value.

Generally, one should use a global const instead of a comptime field. The reason for using a comptime field is when you want reflection over struct fields to find the data as a field. For example:

const std = @import("std");

fn dump(args: var) void {
    inline for (std.meta.fields(@typeOf(args))) |field| {
        std.debug.warn("{} = {}\n", field.name, @field(args, field.name));
    }
}

pub fn main() void {
    dump(.{
        .int = 1234,
        .float = 12.34,
        .b = true,
        .s = "hi",
        .T = [*]f32,
    });
}

This will construct an anonymous struct with all comptime fields and pass it to dump. Each iteration in the for loop will evaluate the @field(...) expression and produce a comptime value.

This is a prerequisite to #208 which is already accepted.

@andrewrk andrewrk added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Nov 13, 2019
@andrewrk andrewrk added this to the 0.6.0 milestone Nov 13, 2019
@andrewrk
Copy link
Member Author

See #208 (comment) for @Hejsil's alternate proposal for how to solve this problem.

@marler8997
Copy link
Contributor

This is a good read:

https://guide.elm-lang.org/appendix/types_as_sets.html

When you view types as "sets of values", it's true that any type that only has 1 possible value does not require any memory to represent. In Zig:

const Foo = enum {A};

the Foo type takes 0 bits to represent. However, enums are only integer values. Providing the ability to create new fundamental types could have some benefits. For example, the type set that has no values could be used as a return type to represent a function that does not return. If we assume @Never() represents this type with no values, then this function would never return:

fn func() @Never() { ... }

Making full use of the type system can result in less additions to the language making things simpler overall.

Knowing these things, the onePossibleValue mechanism sounds promising to solve this issue.

@marler8997
Copy link
Contributor

marler8997 commented Nov 13, 2019

By the way, here's an implementation of oneValueType with current zig:

fn OneValueType(comptime value: var) type {
    const TheEnum = enum { OneValue };
    return union(TheEnum) {
        OneValue: @typeOf(value),
    };
}

However, this doesn't work since any argument you pass to OneValueType will have a type with many possible values.

@marler8997
Copy link
Contributor

And another way you could define the @Never() type would be with an empty enum. This function would never return:

fn foo() enum {} {...}

@JesseRMeyer
Copy link

Is there a reason why 'comptime' is used to qualify b instead of 'const'? I feel I'm missing a nuance here. Consider that Default Field Values are implicitly comp-time known, and this proposal seems to add constness semantics on-top of DFVs.

@Rocknest
Copy link
Contributor

I don't understand why a new type or field type is needed. I think it would be better to have

try @comptimeLoad(struct, name);

Is it possible?

@andrewrk andrewrk added the accepted This proposal is planned. label Dec 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

4 participants