# \[ANN\] CallableModules.jl – Make Julia modules callable

**URL:** <https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341>\
**Category:** Package Announcements\
**Created:** [March 23, 2026, 11:58am UTC](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341 "2026-03-23T11:58:55Z")\
**Posts on this page:** 10\
**Page:** 2

<div class="post-metadata">

**Author:** ![PatrickHaecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickhaecker/32/222891_2.png) [@PatrickHaecker](https://discourse.julialang.org/u/PatrickHaecker)\
**Post date:** [March 25, 2026, 5:10am UTC](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341/21 "2026-03-25T05:10:39Z")

</div>

> [@Mason](#):
>
> That said, I will say that while I think the way you’ve gone about this seems rather dangerous, I do kinda think the concept of callable modules is kinda nice.

Thanks. I think it’s worth that we as a community explore that space and see where it really brings a benefit. There are advantages to explore this with an implementation in `Core` (no type piracy) and there are advantages to do this with a (registered) package (can be archived if no longer used or superseded). But anyway, it seems to be an interesting degree of freedom to have opening up a new corner in the design space.

> It’d be cool if there was a better way to achieve that.

We currently have two ideas as far as i know:

- Moving it into `Base`/`Core` to avoid the type piracy problem
- Having each module being a separate type

From a theoretical point of view I currently prefer the second option, but we’d need a complete list of the implications this would have and see whether there are other options. But having multiple strong use cases first might be the better order.

> [@rayegun](#):
>
> As another aside I realized just now that I don’t have any CamelCase binaries (on my PATH) on any of my machines… The convention of lower case binaries matches Julia functions.

Indeed, they are … controversial (seems to be the general theme of this discussion). Some languages like Java use them due to similar reasons. However, I agree that a lower-case command line interface app name might make more sense.  
But even with a lower-case CLI, this still keeps the module name identical to the Julia interface using CallableModules.jl. It circles again around the point raised above: Although having an interesting design space, we might lack use cases which are convincing enough.

---

<div class="post-metadata">

**Author:** ![PatrickHaecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickhaecker/32/222891_2.png) [@PatrickHaecker](https://discourse.julialang.org/u/PatrickHaecker)\
**Post date:** [March 25, 2026, 6:08am UTC](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341/22 "2026-03-25T06:08:31Z")

</div>

Thanks for everyone taking part in the discussion. I appreciate this and I think it brought up interesting aspects.

I feel like the original intention of this thread has run its course: The package currently is too controversial for being registered, so I will not do this at the moment. This is fine, as the two main intentions of open-sourcing it are

- everyone can use it – for this it does not need to be registered
- avoiding a single point of failure by moving it to a Github community – this does not seem to happen independent of it being registered

My goal is not to cause controversy, but to improve the Julia ecosystem. Therefore, I hope this allows cooling down the discussion a bit so that we can focus on the pros and cons of different interesting aspects which were brought up during the discussion.

Although never explicitly stated, I have the feeling that we need to avoid the following trap:

1. `Base`/`Core` wanting enough exposure in a package first before committing to a new feature.
2. The general registry declining the package containing that feature, because the package contains type piracy, as the feature is not implemented in `Base`/`Core`, but in a package.
3. The unregistered package not getting enough exposure for the feature to be considered adding it to `Base`/`Core`.
4. goto 1

Although each of the steps is totally plausible in isolation, the combination of all steps does not seem to be intended.

Feel free to continue the discussion until the mods think it has also run its course, but I consider the original intention of this topic to be solved.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [March 25, 2026, 7:41am UTC](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341/23 "2026-03-25T07:41:01Z")

</div>

> [@adienes](#):
>
> I tend to agree that the existence of piracy should not preclude a package from General registration. After all, adding a dependency is always opt-in. that said I would generally advise projects, in their individual capacity, to bias away from depending on packages with piracy, and likewise advise authors, in their individual capacity, to avoid using piracy. But there are lots of ways that a package might be designed suboptimally and General can’t possibly hope to police these all.

The problem with piracy is that, unlike some other examples of suboptimal design, it is not constrained just to the package at fault. Piracy potentially breaks any loaded code. So _any_ package can break because an unrelated package does piracy.

IMO if the General registry allows piracy, at the very least the package manager should warn the user about piracy before installing the package that does piracy. When known.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [March 25, 2026, 12:27pm UTC](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341/24 "2026-03-25T12:27:27Z")

</div>

a package that segfaults your process would also “break” other loaded code (in the sense that nothing runs anymore lol), but the General registry can’t forbid the use of `@inbounds` or `unsafe_wrap`

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [March 25, 2026, 12:51pm UTC](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341/25 "2026-03-25T12:51:38Z")

</div>

True, type piracy is similar in this regard to UB. What matters is that the type piracy here is intentional. The proposed package is kinda pure type piracy, that is, the main purpose of the proposed package is type piracy.

The difference is that UB (or type piracy, for that matter) that is a mere bug, such as out of bounds indexing with `@inbounds`, can be fixed in a patch release of the package in question.

In contrast, there is no fixing the package proposed here.

Except for the tenuous possibility that we can somehow ensure both of these:

- JuliaLang/julia v1 will never make use of the method signature in question.

- The General registry will never add any other package that makes use of the method signature in question.

However, at that point a PR to JuliaLang/julia would be simpler anyway.

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [March 25, 2026, 1:11pm UTC](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341/26 "2026-03-25T13:11:52Z")

</div>

> [@nsajko](#):
>
> I feel like @goerz is the principal maintainer of the General registry

No… I am far from the “principal” maintainer of the General registry; and I was only a triage member until very recently. I might be particularly active in superficially reviewing pending registrations, hence maybe the perception. But I certainly don’t have any kind of _special_ authority over package registrations, and will usually defer to more senior registry maintainers when in doubt.

> [@nsajko](#):
>
> assuming we wanted to ensure no such package gets registered ever (again)

We have very few “blanket rules”, and “type piracy” in particular is a complicated issue. Although, personally, I’m very concerned about type piracy, I’m only advocating that type piracy should prevent auto-merge, so that the situation can be discussed in more detail. And even that is speculative.

> [@nsajko](#):
>
> someone would have to step up and commit to review every package registration ever forever. This is not realistic.

A lot of checks can be automated, and we should do more on that front. But beyond that: Any member of the community is encouraged to monitor and review registrations. Triage members have slightly elevated permissions in that they can override certain automerge checks like name similarities, and full maintainers have even more elevated permisions, in that they can manually merge packages. But the system is still built on good-faith-discussion and consensus, and we welcome all comments about concerns with new registrations. I certainly wouldn’t mind if we had a larger group of people who reviewed registrations that are within their sphere of interest. Even beyond superficial things like package naming and the presence of tests or documentation. Keep it constructive, though: the goal is to _help_ people to register high quality packages, and to have a cohesive and rich ecosystem, not to gate-keep.

---

<div class="post-metadata">

**Author:** ![langestefan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/langestefan/32/207923_2.png) [@langestefan](https://discourse.julialang.org/u/langestefan)\
**Post date:** [March 25, 2026, 1:40pm UTC](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341/27 "2026-03-25T13:40:49Z")

</div>

> [@goerz](#):
>
> I certainly wouldn’t mind if we had a larger group of people who reviewed registrations that are within their sphere of interest.

This is what it feels like helping people when there are 10 year veterans in the same thread:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/6/163d6eab92f7d9022c3b768821f8651f954ef93a.jpeg)

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [March 25, 2026, 2:09pm UTC](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341/28 "2026-03-25T14:09:47Z")

</div>

> [@adienes](#):
>
> a package that segfaults your process would also “break” other loaded code

For this to be analogous to type piracy it would need to segfault just from being loaded, which is of course possible, but maybe not that likely in practice. And if it did so consistently it would fail the automerge checks.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [March 25, 2026, 2:12pm UTC](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341/29 "2026-03-25T14:12:56Z")

</div>

> [@rayegun](#):
>
> The convention of lower case binaries matches Julia functions.

Because of the infix operator `-`, many languages can’t use hyphens to separate words in a name, at least not in a way that’s nice to read and write e.g. parsing `var"verb-noun"` to `Symbol("verb-noun")`. Hyphens aren’t the only conventional word separator, but people won’t compromise their conventions for Julia’s parser no matter how justified and willing we are to buck our own naming conventions.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [March 25, 2026, 3:06pm UTC](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341/30 "2026-03-25T15:06:18Z")

</div>

> [@langestefan](#):
>
> > [@goerz](#):
> >
> > I certainly wouldn’t mind if we had a larger group of people who reviewed registrations that are within their sphere of interest.
> 
> This is what it feels like helping people when there are 10 year veterans in the same thread:

Please don’t let these feelings stop you from helping out! The more eyes we have on package registration the better. Some problems are hard to spot, and you might miss them or misdiagnose them, but that’s fine, it’s better than if nobody was watching.

The worst you can do is flag something as problematic that wasn’t actually problematic, and then the registry maintainers can just manually overrule whatever objection you had. That’s totally fine and normal.

If we only rely on vetrans to watch package registrations, soon we won’t have anyone watching them.

[Previous page](https://discourse.julialang.org/t/ann-callablemodules-jl-make-julia-modules-callable/136341.md?page=1)
