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

Ability to make struct members readonly when referenced from another namespace #2479

Closed
ghost opened this issue May 12, 2019 · 5 comments
Closed
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@ghost
Copy link

ghost commented May 12, 2019

Imagine a struct instance with fields that must stay internally consistent. Then it would be helpful to be able to mark these fields as "read only" when referenced outside their own "class/namespace/struct".

// status quo: 
const DelicateState = struct{
	x : u8,
	y : u8, // y must be 60% of z to closest integer - x/2 to closest integer
	z : u8, // z must always be double of x mod 256!
}

// want
const Delicate = struct{
  //"selfmut" marks a variable as mutable only within its own struct/namespace
	x : selfmut u8,
	y : selfmut u8,
	z : selfmut u8,
	
	fn modifyX(self: Delicate, x : u8){
		// set x
		// modify y and z so they are consistent
	}
	fn modifyY ....
	fn modifyZ ....
}

test "Delicate struct" {
	const dct = Delicate.init();
	dct.x = 43; // -> compile time error!
	
	dct.modifyX(43); // -> OK!
	_ = dct.x; // -> OK!
}

This feature is arguably just about helping developers discipline themselves. So it might be out of scope for a low-level oriented language like zig. Though at the same time, this kind of feature can be very helpful for maintainability in larger projects, if that is within zig's scope.

@hryx
Copy link
Contributor

hryx commented May 12, 2019

Related: #2059

Making fields read-only outside a package is an interesting alternative/compromise to fully private fields. I've considered it before but haven't experimented with actually using it yet. I'd recommend a more obvious qualifier such as readonly.

@andrewrk andrewrk added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label May 12, 2019
@andrewrk andrewrk added this to the 0.6.0 milestone May 12, 2019
@daurnimator
Copy link
Contributor

I've been meaning to propose something like this myself!
The http header module (#2263) would benefit from this.

@ghost
Copy link
Author

ghost commented May 15, 2019

I have two other ideas on how to achieve this:
(1) Interfaces. If you want to hide or "protect" implementation details, interfaces are golden.
(2) Comptime. Something like std.access.markSelfMutableOnly({.x, .y, .z}) within the struct in question. This could achieve something similar as a keyword would.

@andrewrk
Copy link
Member

andrewrk commented Jan 5, 2020

This is one of those things where zig is going to not provide a language feature that, admittedly, could be useful, but ultimately is unnecessary to accomplish zig's goals.

@andrewrk andrewrk closed this as completed Jan 5, 2020
@ghost
Copy link
Author

ghost commented Apr 22, 2020

Typedef could be viable for this use case (#5132). See that issue for explanation of the syntax
and semantics.

const ProtectedStruct = typedef(OrigStruct, .Encapsulated{.mode = .FieldsReadOnly} );

test "encapsulated struct" {
   // auto coercion from base to typdef allowed in the context
   // of encapsulation, but casting is required in the other direction. 
   const ps : ProtectedStruct = OrigStruct.init(); 

   ps.field1 += 1; // compile error
   _ = ps.field1; // ok

}

Then you would set ProtectedStruct as the parameter type in function that wants to avoid setting
fields to invalid states, and cast to OrigStruct whenever full access is desired.

OrigStruct would stay blissfully ignorant about encapsulation.

This typedef feature would require the compiler to "consult" what typedef config is associated with
a variable (ZigValue) each time there's a member access operation to either reject or accept.

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

3 participants