# Is Compat.jl worth it for the \`public\` keyword?

**URL:** <https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041>\
**Category:** General Usage\
**Tags:** macros, compatibility\
**Created:** [September 4, 2024, 2:51pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041 "2024-09-04T14:51:50Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [September 4, 2024, 2:51pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/1 "2024-09-04T14:51:50Z")

</div>

With the introduction of `public` by @Lilith, many packages will want to mark their unexported public symbols that way. Since `public` is only available in Julia 1.11, the current recommended way to do this in 1.10 is with the Compat.jl package. Before we add it everywhere, I’m wondering if there are any negative side effects to it? @stevengj seems to think it’s fine but I’d love to get other opinions.

> [@What does the new "public" keyword actually do?](https://discourse.julialang.org/t/what-does-the-new-public-keyword-actually-do/108975/12):
>
> It’s probably installed anyway on your machine, since so many packages use it. And as a runtime dependency it should be quite small — most of it is precompiled away if you have a recent Julia version.

In particular, it depends on 4 stdlibs: `Dates`, `LinearAlgebra`, `TOML` and `UUIDs`.

---

<div class="post-metadata">

**Author:** ![Lilith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lilith/32/27492_2.png) [@Lilith](https://discourse.julialang.org/u/Lilith)\
**Post date:** [September 4, 2024, 3:00pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/2 "2024-09-04T15:00:24Z")

</div>

If you don’t already depend on Compat.jl, I’d recommend

```julia
VERSION >= v"1.11.0-DEV.469" && eval(Meta.parse("public foo, bar"))

```

---

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [September 4, 2024, 3:01pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/3 "2024-09-04T15:01:49Z")

</div>

If it’s such a minimal change, why is there no motivation to add this no-op to v.1.10?  
Because it’s a _dirty hack_?

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [September 4, 2024, 3:03pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/4 "2024-09-04T15:03:23Z")

</div>

Because features are not backported in semver. There’s a rather extensive discussion here:

> [@New Julia LTS? Are many using the current (Julia 1.6) LTS?](https://discourse.julialang.org/t/new-julia-lts-are-many-using-the-current-julia-1-6-lts/93919/28):
>
> No, usually features are not backported, only bugfixes

---

<div class="post-metadata">

**Author:** ![hill](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hill/32/50775_2.png) [@hill](https://discourse.julialang.org/u/hill)\
**Post date:** [September 4, 2024, 4:57pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/5 "2024-09-04T16:57:54Z")

</div>

Is there a way to combine this trick with multiple lines of `public` declarations?

I get a `ParseError` on 1.11.0-rc3 when trying

```Julia
VERSION >= v"1.11.0-DEV.469" && eval(Meta.parse("begin
    public foo
    public bar
end"))

```

---

<div class="post-metadata">

**Author:** ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)\
**Post date:** [September 4, 2024, 5:44pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/6 "2024-09-04T17:44:03Z")

</div>

> [@hill](#):
>
> Is there a way to combine this trick with multiple lines of `public` declarations?

`@static VERSION >= v"1.11" && eval(Meta.parse("""include("public.jl")"""))`

I’ve tried this a while ago without `eval`, generally it worked but had some side effects (not in the code execution, I can’t remember exactly what), and I switched to Compat.jl after the opinion by [stevengj](https://discourse.julialang.org/u/stevengj).

P.S. Discourse makes 2 lines of code out of 1 source line because of &&

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [September 4, 2024, 6:09pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/7 "2024-09-04T18:09:00Z")

</div>

Why not this then?

```julia
@static if VERSION >= v"1.11"
    include("public.jl")
end

```

---

<div class="post-metadata">

**Author:** ![Lilith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lilith/32/27492_2.png) [@Lilith](https://discourse.julialang.org/u/Lilith)\
**Post date:** [September 4, 2024, 6:24pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/8 "2024-09-04T18:24:44Z")

</div>

This should be sufficient:

```julia
VERSION >= v"1.11" && include("public.jl")

```

`@static` partially evaluates expressions at macro-expansion time which is only useful if macro expansion is invalid on a previous version. `include` macro expands just fine on all versions so there’s no need for `@static`.

---

<div class="post-metadata">

**Author:** ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)\
**Post date:** [September 4, 2024, 7:19pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/9 "2024-09-04T19:19:32Z")

</div>

> [@gdalle](#):
>
> Why not this then?

That’s [exactly](https://discourse.julialang.org/t/what-does-the-new-public-keyword-actually-do/108975/9) what I did and now can’t remember what was wrong, but there was something (Documenter.jl, CI, something like that).

---

<div class="post-metadata">

**Author:** ![DanielVandH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielvandh/32/31134_2.png) [@DanielVandH](https://discourse.julialang.org/u/DanielVandH)\
**Post date:** [September 4, 2024, 7:24pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/10 "2024-09-04T19:24:36Z")

</div>

Could’ve been CoverageTools? I had something like it [here](https://github.com/JuliaGeometry/DelaunayTriangulation.jl/actions/runs/9929036519/job/27426085353)

---

<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:** [September 4, 2024, 7:29pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/11 "2024-09-04T19:29:27Z")

</div>

I guess most important is if the tooling that can benefit from that will support any of the alternative ways to declare `public` in 1.10.

---

<div class="post-metadata">

**Author:** ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)\
**Post date:** [September 4, 2024, 7:30pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/12 "2024-09-04T19:30:59Z")

</div>

> [@DanielVandH](#):
>
> Could’ve been CoverageTools?

Well possible.

```julia
VERSION >= v"1.11" && eval(Meta.parse("""include("public.julia")"""))

```

That would probably guarantee there are no CI side effects.

---

<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:** [September 4, 2024, 7:50pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/13 "2024-09-04T19:50:23Z")

</div>

There is also the (proposed, but rejected) [GitHub - JuliaLang/Public.jl](https://github.com/JuliaLang/Public.jl)

That seems small enough so that it could simply be vendored by projects that do not want to use `Compat`

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [September 4, 2024, 7:59pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/14 "2024-09-04T19:59:33Z")

</div>

To ask if something is “worth it” you need to ask about weight on the other side of the scale. What are we talking about here? Maybe a second worth of precompile time, once? Even less? Its four dependences are all (still) old-style stdlibs baked into Julia’s default sysimage, no?

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [September 4, 2024, 10:40pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/15 "2024-09-04T22:40:55Z")

</div>

JuliaSyntax.jl is a new stdlib in 1.10. It defines the new keyword `public` and people want workarounds to work with 1.10 LTS, for package code, though most likely some packages will get left out.

It already has an option `JULIA_USE_FLISP_PARSER` to `1`

It could add `JULIA_ADD_PUBLIC_KEYWORD` env var, off by default, for “compatibilty”/semver reasons. I would rather want it the other way though.

Some stdlibs are upgradable, not sure about that one…

---

<div class="post-metadata">

**Author:** ![mtfishman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mtfishman/32/30755_2.png) [@mtfishman](https://discourse.julialang.org/u/mtfishman)\
**Post date:** [September 4, 2024, 11:09pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/16 "2024-09-04T23:09:42Z")

</div>

Can the dependencies of Compat.jl get turned into weak dependencies through package extensions? I see that was already started with `LinearAlgebra`: [move LinearAlgebra and Dates to package extensions by oscardssmith · Pull Request #790 · JuliaLang/Compat.jl · GitHub](https://github.com/JuliaLang/Compat.jl/pull/790) ( **EDIT:** though for some reason `LinearAlgebra` is still listed as a dependency…).

---

<div class="post-metadata">

**Author:** ![nhz2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nhz2/32/44428_2.png) [@nhz2](https://discourse.julialang.org/u/nhz2)\
**Post date:** [September 4, 2024, 11:25pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/17 "2024-09-04T23:25:23Z")

</div>

When 1.11 comes out, why should packages try and support 1.10? If they want to use a feature in 1.11 why not just keep things simple and set julia compat to 1.11. In my experience adding any nonessential dependencies or weak dependencies quickly leads to dependency hell when working on a complex Julia code base.

---

<div class="post-metadata">

**Author:** ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)\
**Post date:** [September 5, 2024, 12:25am UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/18 "2024-09-05T00:25:27Z")

</div>

If one doesn’t want to use `Meta.parse`, one can say

```julia
VERSION >= v"1.11.0-DEV.469" && eval(Expr(:public, :foo, :bar))

```

---

<div class="post-metadata">

**Author:** ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)\
**Post date:** [September 5, 2024, 7:14am UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/19 "2024-09-05T07:14:43Z")

</div>

> [@nhz2](#):
>
> When 1.11 comes out, why should packages try and support 1.10?

LTS

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 5, 2024, 7:38am UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/20 "2024-09-05T07:38:05Z")

</div>

> [@gdalle](#):
>
> Before we add it everywhere, I’m wondering if there are any negative side effects to it?

Maybe a tiny (pre)compilation time, which you can just benchmark if you are worried about it.

The benefits (cleaner, easier to maintain code) easily outweigh it IMO.

[Next page](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041.md?page=2)
