I also commonly come across modules that are listed in ExDoc but turn out 
to only be part of the implementation of the 'main' module of the library, 
as well as the inverse, where I am myself creating a library and I'd want 
to split stuff up in multiple modules but end up not doing it because I 
don't want to confuse the user of the library with the extra modules.

More importantly than the second point though, is the fact that I actually 
*do* want to have documentation (including possibly doctests) for my 
'private' modules' public functions (So functions that are used by other 
modules in my library). This to:

1. Inform my future self and other contributors to the open source project 
about design choices made in the implementation of certain functions.
2. Sometimes, test these functions. (There is some arguing about this; some 
people say that testing should only occur at the most external layer of 
your library, but I concur because often, libraries end up being nested 
(without it making sense to split stuff into multiple physical libraries)).

I really would like to use the markdown-syntax for this, and also to 
generate ExDoc pages that include this information (as well as showing it 
within IEx). *Of course, with a disclaimer that this function is part of a 
'private' module and should not be used by consumers of the library but 
only by the library itself.*

 @Christopher Keele's trick to still use Markdown-syntax is interesting, 
but since it is not actually compiled to any documentation I don't think it 
is particularly useful.

Personally, I do think that having a way to annotate modules as protected 
or private (Possibly, protected is the more accurate name for this 
functionality?) that would:
- Generate disclaimers on top of documentation, possibly hiding the actual 
documentation behind a 'spoiler'-like tag to make sure that people don't 
glance over the disclaimer.
- Show references to the modules in a different color (i.e. 'faded out') in 
ExDoc (and possibly IEx) to make sure that people see that these modules 
are uninteresting for the outside world.

This would already protect against 95% of the 'bad use'. In the end, if a 
user wants to do something what is bad for them and we have informed them 
that it is bad, it is their own choice, after all.

And yes, maybe we could also have the compiler throw warnings when a user 
does decide to depend on an 'internal' function. But I think that is all 
that is needed.

~Wiebe-Marten Wijnja/Qqwy

On Sunday, December 10, 2017 at 9:34:43 PM UTC+1, Maciej Kaszubowski 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/6a5ac929-6a67-4f1d-a1aa-abe844765bf3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to