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

Proposal: inferred struct field type via default value #2866

Closed
fengb opened this issue Jul 10, 2019 · 5 comments
Closed

Proposal: inferred struct field type via default value #2866

fengb opened this issue Jul 10, 2019 · 5 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@fengb
Copy link
Contributor

fengb commented Jul 10, 2019

I think the fields with default values could be inferred in the same way as variables:

const ZeeAlloc = struct {
    backing_allocator: *Allocator,

    free_lists: [size_buckets]FreeList = [_]FreeList{FreeList.init()} ** size_buckets,
    page_size: usize = page_size,
    allocator: Allocator = Allocator{
        .reallocFn = realloc,
        .shrinkFn = shrink,
    },
}

// compare with

const ZeeAlloc = struct {
    backing_allocator: *Allocator,

    free_lists = [_]FreeList{FreeList.init()} ** size_buckets,
    page_size = usize(page_size),
    allocator = Allocator{
        .reallocFn = realloc,
        .shrinkFn = shrink,
    },
}
@tiehuis tiehuis added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Jul 11, 2019
@dimenus
Copy link
Contributor

dimenus commented Jul 11, 2019

Does this make it harder to easily identify what is a decl and what is a regular assignment? Unlike in func / global scope there's no keyword to make it easily identifiable.

@fengb
Copy link
Contributor Author

fengb commented Jul 11, 2019

Good point. My half-baked idea — prepend the dot like regular struct init:

const ZeeAlloc = struct {
    backing_allocator: *Allocator,  // possibly always prepend?

    .free_lists = [_]FreeList{FreeList.init()} ** size_buckets,
    .page_size = usize(page_size),
    .allocator = Allocator{
        .reallocFn = realloc,
        .shrinkFn = shrink,
    },
}

@tiehuis
Copy link
Member

tiehuis commented Jul 11, 2019

I don't know about this proposal. I think adding a new way of
performing default-field initialization would lead to a mismatch in style and
wouldn't be beneficial. I also suspect that more complicated default-field
initializations (e.g. structs, arrays) which this would improve the most, may
not be common enough to be a compelling reason. This is just an assumption on
my part after a bit of use, though.

Specifically about the style-mismatch, this brings up implicit casting vs.
explicit type parameters. There is an existing proposal about adjusting the
implicit-casting syntax which may or may not reduce the impact of this
proposal: #1757. There are actually some other related things in that issue
but I'll leave them for now.

struct {
    a: usize = 5,
    b: ?Foo = null,
}

struct {
    a = usize(5),
    b = (?Foo)(null),
}

The latter style of nullables is rarely used currently. You could argue that
you could mix and match styles, but we usually "prefer one way to do things"
where reasonable.

@fengb
Copy link
Contributor Author

fengb commented Jul 11, 2019

The style mismatch already exists with regular variable declarations:

var a: usize = 5;
var b = usize(5);

struct {
  a: usize = 5,
  b = usize(5),
}

I just think the semantics are similar enough to warrant similar syntax.

@andrewrk andrewrk added this to the 0.6.0 milestone Jul 12, 2019
@mikdusan
Copy link
Member

mikdusan commented Jul 26, 2019

On the styling, I've been musing about dot-syntax to differentiate between field vs. namespace decls and dropping "comma" with some added benefits:

  1. replace a: u32, field decl syntax with .a: u32;
  2. add field decl inferral syntax: .b = false;
  3. idiomatic init() routines now have a chance to self-reference values/addresses during copy-elision return
const Foo = struct {
    .some_flag = false;
    .arena_storage: std.heap.ArenaAllocator;
    .arena: *std.mem.Allocator;

    fn init(backing: *std.mem.Allocator) Foo {
        return Foo{
            .arena_storage = std.heap.ArenaAllocator.init(backing);
            .arena = &.arena_storage;
        };
    }
};

this has the consequence of... changing how field initialization looks (commas now become semicolon):

var a = Car{ .a = 1; .b = 2; .c = 3; };
var b = Car{ .a = 1; .b = 2; .c = a+b; };

@andrewrk andrewrk modified the milestones: 0.6.0, 0.7.0 Feb 10, 2020
@andrewrk andrewrk modified the milestones: 0.7.0, 0.8.0 Oct 27, 2020
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 May 19, 2021
@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 Nov 23, 2021
@andrewrk andrewrk modified the milestones: 0.10.0, 0.11.0 Apr 16, 2022
@andrewrk andrewrk modified the milestones: 0.11.0, 0.12.0 Apr 9, 2023
@andrewrk andrewrk modified the milestones: 0.13.0, 0.12.0, 0.11.0 Jul 9, 2023
@andrewrk andrewrk closed this as not planned Won't fix, can't repro, duplicate, stale Jul 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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

5 participants