Sure, I agree with you that it would probably be possible to use such functions anyway, but I don't think it's much of an issue.
The problem I'm trying to solve here is not that calling such function would be "a mistake which could be prevented". My point is not to prevent mistakes, but to have a way to enforce boundaries and clear design of applications. I think the analogy to private functions is really helpful to explain this. Calling a function that's private wouldn't usually cause a bug, but doing so makes your module more maintainable and flexible because you can change the implementation details while being sure that nobody relies on. Private/protected modules would have the same effect but on the application, not module level. While it will really help to develop client-facing applications, I think it would help maintainers of libraries (including Elixir itself) even more. Just think about how many issues are opened by people using undocumented functions from modules which are used internally but aren't supposed to be called by external clients. This is quite a huge problem because there's no way to know this without looking at the documentation and can be easily missed while reviewing the code. With the proposed feature, we could have a clear distinction (enforced be a compiler) what is safe to call and what is not. If someone would like to call the function anyway (for example by using `apply/3`), this would at least be clear that it's not a correct solution to a problem. W dniu niedziela, 10 grudnia 2017 21:57:13 UTC+1 użytkownik Paul Schoenfelder napisał: > > I think the only viable way to do something akin to "protected" modules, > would be to have the compiler verify it, but generate public modules - this > achieves the goal of protecting against improper use for the most part. > That said, there are still ways to violate these boundaries, say by using > `apply/3` or by assigning a module name to a binding and then calling a > function via the binding. That's just the nature of dynamic languages > though; the average case would still be protected anyway. > > I'm not sure if this is really the right way to solve this particular > problem though - I can't think of a situation I've encountered where I was > like "this mistake wouldn't have been made if this module was protected". > That said, I don't think it's a bad idea, but since it is not a guarantee > and is rather easy to violate, it doesn't feel like the right solution. > > Paul > > > On Sun, Dec 10, 2017 at 2:34 PM, Maciej Kaszubowski < > [email protected] <javascript:>> wrote: > >> Hello, >> >> *What?* >> >> I would like to propose introducing a possibility to make a module >> protected/private. Functions from such module would not be visible outside >> of the OTP application they are defined in. >> >> *Why?* >> >> Currently, all modules included in the release are globally visible. This >> makes it harder to enforce correct architectural boundaries because we have >> no support from the compiler. We can only enforce the boundaries by being >> careful or by running external scripts, but both solutions fall short when >> the developers are under pressure or before deadlines. >> >> It would be nice if it was possible to create a module which can only be >> accessed from the inside of a library/application where it's defined. We >> have private functions, so it would be nice if we could do the same for >> modules which are one abstraction level higher. This would allow to clearly >> define a public interface for libraries/applications which would result in >> better design. Since one of the recent Elixir goals is to help creating >> maintainable software, I think this feature would be a really good step in >> this direction. >> >> *Issues* >> >> Proposed behaviour could be problematic due to the fact that all Elixir >> modules compile to Erlang modules which are all public. I came up with >> three possible ways to handle this: >> >> 1. Compile all modules modules as usual (resulting in public Erlang >> modules), but have Elixir compiler fail when the function from >> private/protected module is called. >> 2. Don't create Erlang modules from private/protected Elixir modules and >> "copy" the functions to public modules that use them. >> 3. Treat all modules are public and use mix xref task to validate this >> behaviour outside of the compilation step. >> >> All of the solutions have advantages and disadvantages and maybe there >> are some others which I didn't think of. >> >> I'll be happy to know what you think about this. >> >> Cheers, >> Maciej >> >> -- >> You received this message because you are subscribed to the Google Groups >> "elixir-lang-core" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected] <javascript:>. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/elixir-lang-core/ba637c6c-ea48-4bb2-be1f-3758dd901ced%40googlegroups.com >> >> <https://groups.google.com/d/msgid/elixir-lang-core/ba637c6c-ea48-4bb2-be1f-3758dd901ced%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/a882d76b-c849-4796-ad1a-653a19b03e4c%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
