# Advanced submodule: Pattern or Anti-pattern?

**URL:** <https://discourse.julialang.org/t/advanced-submodule-pattern-or-anti-pattern/63894>\
**Category:** General Usage\
**Created:** [July 1, 2021, 2:30pm UTC](https://discourse.julialang.org/t/advanced-submodule-pattern-or-anti-pattern/63894 "2021-07-01T14:30:04Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [July 1, 2021, 2:30pm UTC](https://discourse.julialang.org/t/advanced-submodule-pattern-or-anti-pattern/63894/1 "2021-07-01T14:30:04Z")

</div>

The package in question has a handful (about 10) simple ‘main API’ functions. Most of those functions follow the pattern of examining the user input a bit, then selecting some combination of more generic functions to call.

Using those more generic functions directly the package is capable of a bit more than what the simple ‘main API’ functions expose but they are more verbose and difficult to use correctly. At least in my mind there is a clear distinction between the simple, the generic and the internals.

I suppose one way is to just export the generic stuff as well, but it is a significantly larger set than the set of simple functions. It is also significantly smaller than the set of internal stuff.

One thought that popped to my mind was to have an Advanced submodule which exports the generic stuff. Putting the generic in a separate package is another option, but that would make the main package look a bit silly and I also suck at naming packages. It is also a bit of a refactoring effort given that the package exists already.

I know there is no definitive answer here, but I’m looking for some opinions and consequences might not be trivial to help guide my decision.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [July 1, 2021, 2:41pm UTC](https://discourse.julialang.org/t/advanced-submodule-pattern-or-anti-pattern/63894/2 "2021-07-01T14:41:31Z")

</div>

Plots does something like that, for example:

```julia
using Plots
import Plots.Measures: mm # to define margins, for example
plot(rand(10),margin=10mm)

```

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [July 2, 2021, 2:48am UTC](https://discourse.julialang.org/t/advanced-submodule-pattern-or-anti-pattern/63894/3 "2021-07-02T02:48:21Z")

</div>

I usually like that pattern. e.g

```julia
Foo.LowLevel
Foo.Hazmat

```

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [July 2, 2021, 3:26am UTC](https://discourse.julialang.org/t/advanced-submodule-pattern-or-anti-pattern/63894/4 "2021-07-02T03:26:48Z")

</div>

I do something like this with Elfel.jl:  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/e/9ea9c31c1125a170b05ef5839a5da747c28f4263.png)

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [July 3, 2021, 11:19am UTC](https://discourse.julialang.org/t/advanced-submodule-pattern-or-anti-pattern/63894/5 "2021-07-03T11:19:32Z")

</div>

Thanks, I’ll give it a shot then.

I suppose one drawback is that one must step the breaking rev whenever `Advanced` breaks which means that even users who don’t need it must step the compat bounds.

I suppose one can also declare that `Adanced` is not part of the public API but I think that is worse as it would force anyone using it to set very strict compat bounds whereas the former can be handled e.g. by communicating in the release notes (and is kinda automatically solved by CompatHelper and CI).

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [July 3, 2021, 6:28pm UTC](https://discourse.julialang.org/t/advanced-submodule-pattern-or-anti-pattern/63894/6 "2021-07-03T18:28:29Z")

</div>

Another option is to have a FooCore.jl with the advanced API and a Foo.jl with the friendly API, upgraded separately and depending on FooCore.jl.

Now that I think of it, I don’t really see any downsides to this and it helps keep the boundaries clear.

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [July 4, 2021, 5:48pm UTC](https://discourse.julialang.org/t/advanced-submodule-pattern-or-anti-pattern/63894/7 "2021-07-04T17:48:12Z")

</div>

Yeah, that is probably the best way all in all.

In this case the only drawback would be the effort to separate the code into two packages as the package already exists.
