Yes, you can add `@moduledoc false`, but that doesn't really solve the 
problem. For me this is not enough, just like adding a comment saying 
"Please don't use this" wouldn't be enough if we didn't have private 
functions available. 

In my opinion, strong boundaries between components are key to creating 
maintainable software. Having a strong way to enforce them (by throwing a 
compile error) would really help. All the other methods (including 
`@moduledoc false`) rely on "good discipline" of developers - something 
that quickly disappears before the deadline. 

Now, I know this isn't an easy feature to add and I don't expect it to be 
added soon, but I strongly believe that it would have a great impact on 
maintainability of the software we create. For me, we should be really 
careful with arguments based on the way Erlang works. Erlang is a really 
mature solution and it's perfectly understandable that the rate of change 
is slower. In Elixir, we can move quicker and improve the language. What's 
more, the change wouldn't have to break backwards compatibility or 
compatibility with Erlang. The code could be still compiled to public 
Erlang modules, but Elixir could enforce the boundaries. It's a win-win 
situation in my opinion. 

W dniu wtorek, 12 grudnia 2017 00:52:17 UTC+1 użytkownik Christopher Keele 
napisał:
>
> 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/75b11d2b-c55d-4f9b-87bd-910d8e820d6e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to