# 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:** 18\
**Page:** 2

<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 5, 2024, 7:40am UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/21 "2024-09-05T07:40:32Z")

</div>

I thought so too at first, but I got worried after some people asked me to remove the SparseArrays stdlib from DifferentiationInterface.jl because it adds 300ms of load time ^^ Didn’t think stdlibs would be such a sensitive issue.

---

<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:** [September 5, 2024, 8:28am UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/22 "2024-09-05T08:28:39Z")

</div>

Why not just do

```julia
macro public(ex)
    if VERSION >= v"1.11.0-DEV.469"
        args = ex isa Symbol ? (ex,) : Base.isexpr(ex, :tuple) ? ex.args : error("something informative")
        esc(Expr(:public, args...))
    else
        nothing
    end
end

@public x, y

```

?

I strongly doubt this is worth bringing in Compat.jl for, that package is quite hefty with lots of piracy and invalidations.

---

<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 5, 2024, 1:02pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/23 "2024-09-05T13:02:09Z")

</div>

Why that macro, and where to put it? Or why not the subtly different public macro (I’m not sure which is better, and it also has a bit more code) in the (“unpopular”) unregistered package:

> <https://github.com/JuliaLang/Public.jl/blob/a0e40de2b67a255dee7ffdf392e7b794eb49d44f/src/Public.jl#L9-L19>

---

<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:** [September 5, 2024, 1:12pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/24 "2024-09-05T13:12:03Z")

</div>

> Why that macro

… So that you can use `public` on versions that support it without dropping support for old versions?

> and where to put it?

In your package if you really feel the need to use `public` and support old versions.

> Or why not the subtly different public macro (I’m not sure which is better, and it also has a bit more code) in the (“unpopular”) unregistered package:

Well, one reason I suggested the above macro is that I had never heard of that package before. Another reason would be that, as you said, its unregistered, so actually **using** it might end up being tricky.

Besides, this is really just such a simple macro I don’t think it particularly needs to be a dependency.

---

<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 5, 2024, 1:21pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/25 "2024-09-05T13:21:56Z")

</div>

> [@Palli](#):
>
> where to put it?

Some Julia packages include a `src/compat.jl` file that contains relevant snippets from Compat.jl to avoid a full dependency. You could add this macro to such a file.

---

<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, 1:24pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/26 "2024-09-05T13:24:21Z")

</div>

> [@Palli](#):
>
> in the (“unpopular”) unregistered package

AFAIK that did not go anywhere and recommended solution is either Compat.jl, or manually including the macro (as in the examples above). see the discussion for

> <https://github.com/JuliaLang/Public.jl/pull/1>

---

<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 5, 2024, 1:56pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/27 "2024-09-05T13:56:47Z")

</div>

I choose to recommend `Meta.parse` over manual `Expr` creation because `Meta.parse` is more clearly a public API while manual Expr creation is more ambiguously public.

---

<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 5, 2024, 2:17pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/28 "2024-09-05T14:17:05Z")

</div>

I’m sorry but I still don’t understand why macros or manual parsing would be better than the conditional `include` suggested earlier. Does anyone have a simple explanation?

---

<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:** [September 5, 2024, 2:25pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/29 "2024-09-05T14:25:37Z")

</div>

I suppose it depends on whether you want to have all your `public` declarations collected in one file or if you want to declare things public close to their definition.

---

<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 5, 2024, 2:27pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/30 "2024-09-05T14:27:37Z")

</div>

As the user of a package, I’d like to be able to open the main file and quickly skim the `export`s and public API.

---

<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:** [September 5, 2024, 2:39pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/31 "2024-09-05T14:39:15Z")

</div>

> [@hill](#):
>
> 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"))
> 
> ```

In general there’s something fishy with the parsing of `public`, regardless of compat considerations. One would expect it to parse similar to `export`, but it doesn’t.

```julia
julia> begin
           export foo
       end

julia> begin
           public foo
ERROR: ParseError:
# Error @ REPL[3]:2:12
begin
    public foo
# └─┘ ── Expected `end`
Stacktrace:
 [1] top-level scope
   @ REPL:1

```

and

```julia
julia> :(export foo)
:(export foo)

julia> :(public foo)
ERROR: ParseError:
# Error @ REPL[5]:1:10
:(public foo)
# └─┘ ── Expected `)`
Stacktrace:
 [1] top-level scope
   @ REPL:1

```

---

<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:** [September 5, 2024, 2:58pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/32 "2024-09-05T14:58:51Z")

</div>

Would you mind submitting that as an issue to JuliaSyntax.jl?

---

<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:** [September 5, 2024, 3:11pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/33 "2024-09-05T15:11:46Z")

</div>

[Done](https://github.com/JuliaLang/JuliaSyntax.jl/issues/502).

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [September 5, 2024, 3:13pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/34 "2024-09-05T15:13:38Z")

</div>

I believe it was intentional to not be breaking: `public` is only a keyword at toplevel). Was discussed in [https://youtu.be/2o8MhoN-3NE?si=KHs9yiHmV6b6C4Hq](https://youtu.be/2o8MhoN-3NE?si=KHs9yiHmV6b6C4Hq) too.

---

<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 6, 2024, 8:50pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/35 "2024-09-06T20:50:50Z")

</div>

See also: [Add alternative compat for public other than Compat.jl by LilithHafner · Pull Request #55097 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/55097) which adds

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

```

to the manual at [Modules · The Julia Language](https://docs.julialang.org/en/v1.12-dev/manual/modules/#Export-lists)

---

<div class="post-metadata">

**Author:** ![krynju](https://avatars.discourse-cdn.com/v4/letter/k/ecccb3/32.png) [@krynju](https://discourse.julialang.org/u/krynju)\
**Post date:** [September 6, 2024, 9:46pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/36 "2024-09-06T21:46:37Z")

</div>

One known side effect of unnecessairly importing Compat.jl is this package compiler issue, but it’s a pretty niche use case, so it’s unlikely to be a problem for you [Type piracy on `Base` fails incremental sysimage builds (1.9 -\> 1.10 regression) · Issue #924 · JuliaLang/PackageCompiler.jl · GitHub](https://github.com/JuliaLang/PackageCompiler.jl/issues/924)

I’m personally not a fan of Compat.jl. It changes the global execution environment for users without their knowledge (if it lands in their Manifest) and it’s basically a type piracy factory (on Base) if used with a lower than latest Julia version.

I would rather avoid adding it to packages unless absolutely necessary. There are a few issues about side effects of Compat.jl being present implicitly in user environments, so I’d rather not contribute more to the issue

---

<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:** [February 11, 2025, 8:12pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/37 "2025-02-11T20:12:09Z")

</div>

Sorry for necroposting but how would one extend this macro to make macros public? `@public @mymacro` doesn’t seem to work

---

<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:** [February 11, 2025, 9:10pm UTC](https://discourse.julialang.org/t/is-compat-jl-worth-it-for-the-public-keyword/119041/38 "2025-02-11T21:10:10Z")

</div>

I think you’d use `@public var"@mymacro"`, but I imagine you could also change the definition to support this without the `var`.

```julia
julia> macro public(ex)
           if VERSION >= v"1.11.0-DEV.469"
               args = ex isa Symbol ? (ex,) : Base.isexpr(ex, :tuple) ? ex.args : error("something informative")
               esc(Expr(:public, args...))
           else
               nothing
           end
       end
@public (macro with 1 method)

help?> @public
  No documentation found for private symbol.

  @public is a macro.

  # ...

julia> @public var"@public"

help?> @public
  No documentation found for public symbol.

  @public is a macro.

```

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