Reasoning why private method of struct is accessible from within the same file

According to the documentation, pub specifier takes effect only when the decl is imported by @import():

The pub specifier allows the function to be visible when importing.

So we can access a private function of a struct if the struct is defined in the same file:

const Struct = struct {
    fn private_fn() void { ... }
};

test {
    Struct.private_fn();
}

I sometimes want that non-pub functions are inaccessible outside the structure. If there’re some reasoning for this behavior, I appreciate it.

I think the reasoning might be so that you can have helper methods/other private functions that use private functions without forcing those private functions to become public, just so they can be used by helper methods or other private functions.

(For example when you have multiple structs with private functions defined in one file and they use each others private functions, but just expose a much simplified public interface)

If there wasn’t something like this, you would easily end up in situations where you need to make many functions public that you don’t really want to make public. Which would mean that you constantly have to put them in private folders where they are defined as public but per convention namespaced as something that is considered private.

I think it is easy enough to put it in a different file, when you really want the private methods to be inaccessible.

I also think it simplifies implementation when everything within a file is just accessible, because then it is just a matter of whether there is some declaration within the file or not, without having to manage granular permissions within a file.
It also would be annoying if you couldn’t access some internal constant just because it is defined in some locally scoped namespace.

4 Likes

Experience with other languages shows that if you hide things with private access, users will find ways to circumvent it anyway (often with egregious hacks). Better to stay out of your user’s way.

It is gentler on your users to document proper usage, and where necessary, introduce frictions to doing things that you consider improper. e.g. put ‘private’ stuff in an inner “impl” struct, using a leading _ in the name or similar “this is private” naming convention (and documenting it).

Essentially the “why” is the wisdom of the BDFL. This topic has been extensively discussed and bikeshedded, and the conclusion has been that the downsides of it (including adding complexity to the language/compiler) outweigh the theoretical benefits.

1 Like