Private struct members

Will Mojo support private struct members, or is that discussion settled as part of the let discussion?

I believe the underscore convention of Python is misplaced in a strongly typed language like Mojo. Leading underscores make the code more difficult to read and write, and are easy to forget, like List.capacity, which is missing an underscore, and whose mutation quickly leads to a segfault. It also makes it necessary to implement get_name or __getattr__ methods to prevent library users from performing unintended mutations.

I propose the following syntax, but have no strong opinion here.

struct OptInUsingRead:
    var public: Int   # same as ref var public: Int
    read var private: Int

This discussion has mostly been tabled. I personally want to have public/private, but I also think that the author of the final executable binary should get an override, so my suggestion in the previous discussion of this issue was to leave public/private until we have a reflection API where a developer can grab a struct member by name even when it is private, albeit with a lot of ceremony. Once that escape hatch exists, then many of the potential issues of public/private, such as library authors not exposing all relevant data or needing to access private members for unit tests, go away.

2 Likes

Thanks for answering! Isn’t that escape hatch already available using the following?

UnsafePointer(to=name).origin_cast[True, MutableOrigin.cast_from[__origin_of(name)].result]()[]

You can get a pointer to the object using that method, which invokes a whole host of UB, but if we had private fields that still wouldn’t give you a pointer to the field, you’d need __offset_of() or similar since Mojo technically doesn’t define a layout for structs.

1 Like

Ah, sorry for the confusion. In my head private members in Mojo would be readable, i.e. accessable as an immutable references. Would having readable members be an option? Then the escape hatch I mentioned should work.

At that point, it’s probably better to just have a getter function rather than make it a language feature.

Then we are back to using leading underscores everywhere for the “real” variables, but I agree that this works. Thanks for taking the time to reply! :blush:

I also really want to have this at some point, but this is “easy to work around”, so it isn’t a priority in the immediate future.