>
> 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.

Reply via email to