Zig: New keyword "field" for struct/enum instance variables/functions.

Created on 9 Jul 2019  路  9Comments  路  Source: ziglang/zig

In Zig, the difference between "namespace members" of a struct (or other container like enum) and "instance members" could be more explicit. Compare with Java, where "namespace members" would be designated with the static keyword.

It's not much of a problem right now, but if later on Zig will add more access modifiers to fields, then it could be helpful when you see const field x: i32, to know that it is different from const x: i32, or from field x: i32. Here, const field would open up the possibility to mark an instance member as immutable.

// currently
const S = struct{
  x: i32,
  y: i32,
  var z: i32 = 0;
  const t: i32 = 5;

  fn add(self: S, other: S) S{
    ....
  }
}

// more explicit
const S = struct{
  field x : i32,
  field y : i32, 
  var z: i32 = 0;
  const t: i32 = 5;

  fn add(self: S, other: S){
    ....
  }
}
proposal

Most helpful comment

Slightly related, this could also allow a more unified declaration syntax with regard to commas and semicolons: Static members fields are terminated by ; and non-static member fields by ,. I believe that adds a bit of confusion, and having a different way of stating 'static-ness' could also enable an alternative syntax where every struct member is terminated in the same way.

All 9 comments

"Explicit" might be the wrong term to describe the goal here. I think what your proposal perhaps offers is more immediate readability. In my opinion that's up for debate, as the mandatory presence of var or const on a decl is a pretty good giveaway.

I do think this would look better at top level scope.

One downside is it makes anonymous structs more tedious. field is also a pretty common variable name.

"Explicit" might be the wrong term to describe the goal here. I think what your proposal perhaps offers is more immediate readability. In my opinion that's up for debate, as the mandatory presence of var or const on a decl is a pretty good giveaway.

I don't think it's very difficult to see the difference between instance members and namespace members either, but this "explicitness" might make it easier to add modifiers to fields later on, e.g that field const could mean that this field is immutable, field alone could mean that the variable is readonly outside its own namespace, while field var could let this field be modifiable everywhere. There's also the existing pub keyword though. Related: #2479

I do think this would look better at top level scope.

One downside is it makes anonymous structs more tedious. field is also a pretty common variable name.

I see your point. Here's some ideas (of varying quality) on alternative names: field -> fld, member -> mbr, instance -> inst, part -> prt, piece, component -> comp, cmp, element -> elm

Slightly related, this could also allow a more unified declaration syntax with regard to commas and semicolons: Static members fields are terminated by ; and non-static member fields by ,. I believe that adds a bit of confusion, and having a different way of stating 'static-ness' could also enable an alternative syntax where every struct member is terminated in the same way.

How about a keyword to document static members instead? That style is pretty common from the Java syntax family and it keeps most of the noise down:

const S = struct {
  x : i32,
  y : i32, 
  static var z: i32 = 0,
  static const t: i32 = 5,

I really don't like the static keyword though...

I'm in favor of not polluting non-static members with a designator, that would just make it feel more verbose.

Unifying struct and function syntax could also be considered.

const Example = struct( ...instance members go here... ){... namespace members go here...}
const S = struct(x: i32, y: i32){  fn add(self: S, other: S){} }
const E = enum(ON, OFF, UNKNOWN){}
const U = union(ERROR: MyError, Result: MyPayload){}
const F = fn(x: i32, y: i32){} // functions already "look" like this.

Parenthesis behind the enum and union keywords are already used for something though. Ordinal values for enums and making tagged unions. And for structs with a lot of instance members, you would need two multi-line scopes for one struct.

I do think this would look better at top level scope.

One downside is it makes anonymous structs more tedious. field is also a pretty common variable name.

I know you're not necessarily amenable to this idea, but if top-level readability is a concern, and since every zig file is a struct, you might consider forcing every file's contents to be in an anonymous struct expression, i.e.:

// can't write code here
struct {
    ... // your code here
} // <-- no semicolon because this is an expression, not a statement
  • This is what every language that has "every file is a struct/class" does that I'm aware of.

  • Semantically, this also makes sense for @import to evaluate the imported file as an anonymous struct expression at the callsite. It fits really well with the rest of zig because all struct declarations already use anonymous struct expressions.

  • It's more explicit. Newcomers would not know that each file is a struct and it feels a bit counterintuitive for people coming from other languages to be able to declare fields in the top-level scope of a file.

  • It's trivial to type. There's no naming concern since it's an anonymous struct, compared to C# and Java where you have to come up with a class name before you begin coding.

Making an executive decision to stick with status quo on this one.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jorangreef picture jorangreef  路  3Comments

andrewrk picture andrewrk  路  3Comments

andrewrk picture andrewrk  路  3Comments

zimmi picture zimmi  路  3Comments

S0urc3C0de picture S0urc3C0de  路  3Comments