> > Functions from such module would not be visible outside of the OTP > application they are defined in.
Currently, all modules included in the release are globally visible. As module references are just atoms, I can't think of a good way to hide the modules, just the functions within them by making them private or undocumented. For what its worth, when I want to document a module or function but hide it from exdoc, iex, and other tooling, I just do: defmodule Secret do @moduledoc """ Docs go here! """ && false end If such a module falsified all its docs as well as its moduledoc, I suspect you'd get many of the benefits of a 'private' module you're seeking without having Elixir have to add new compiler abstractions and diverge substantially from how erlang compiles today. On Sunday, December 10, 2017 at 1:18:22 PM UTC-8, Maciej Kaszubowski wrote: > > 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]> 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]. >>> 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/cf95e685-d647-4335-a3ea-cf7e67174c2d%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
