-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: Base.@public
macro for declaring a public name without needing to export
it
#42117
Comments
Thank you, It'd be indeed nice thing to have! To fill some details, I think it helps considering nested modules and " module A
export B
@public C
module B
export f1
@public f2
end
module C
export f3
@public f4
end
module D
export f5
@public f6
end
end I'd consider Also, it'd be nice if
So, given the above point, I think you'd want to return, say, Also, why not something based on optional keyword, like
It'd be really cool if Registrator.jl can enforce (a part of) semantic versioning like Elm does. Ref: Enforce SemVer like Elm? - Internals & Design - JuliaLang; Also Do people want cargo to enforce SemVer like elm-package does? : rust |
An alternative approach to baremodule Foo
export cool_stuff # public and exported
function fit end # public but not exported
function cool_stuff end
module Internal
import ..Foo: cool_stuff, fit
function private_stuff end # private
end
end # module and consider I'm actually using this pattern in most of my recent packages. You can see how it looks like in, e.g., https://github.com/tkf/Reagents.jl/blob/22114bef7331b4ad3d604af5f3255a3fe94f9060/src/Reagents.jl#L1 An upside is that the user can't do Of course, |
As an alternative to creating a new function There is already an
|
Another thing to consider may be that (1) Some call signatures of the constructor of a type may be considered internal. A strict interface can be implemented with function _S end
struct S
...
global _S
_S(...) = new(...)
end
S(...) = _S(...) # public constructor but it's rather tedious. (2) It's not clear if adding type parameters at the end of the parameter list is considered non-breaking (this is the "call signature" of f(::S{T}) = ...
f(::Tuple{S{T}}) = ... can survive the update but struct R
f::S{T}
end
f(::Pair{S{T}}) = ... can't. This, of course, depends on the exact guarantee provided by the API. But it is somewhat unsatisfactory that a basic question like "can this be called?" cannot be answered by looking at the meta data created by (3) Similar to point (2), changing struct type to abstract type may or may not be considered breaking depending on the exact API. Possible solution to (1)The point (1) can be solved by, e.g., extending @public struct S
...fields...
end is lowered to @public S
struct S
...fields...
Base.construct(::Type{S}, fields...) = new(fields...)
end so that it's easy to expose limited set of call signature from the constructor by defining Possible solution to (2) and (3)A simple-minded solution to (2) and (3) may be to define that:
|
Doesn't My idea for Personally, I think that if we have differences in the semantics between |
The counter-argument to my previous comment is that just because |
Right, maybe a more important discussion is "if |
I played with the interface suggested in the OP: https://github.com/JuliaExperiments/PublicAPI.jl. It's also possible to add some stricter interfaces like detecting undefined public names and imports of internals. |
With the planned separate-compilation feature, nonpublic names could be excluded from built library artifacts. |
I understand that to mean "export docs", like declaring that docs & the associated object/function is intended to be used by users of the package. Things that are then either |
It would probably be useful to hook |
Continued in #48819 |
This was implemented in #50105 |
Summary
I would like to give package developers a way to declare names that are part of their package's public API without needing to
export
them.This feature request has two parts:
Base.@public
macro, which declares a name as public withoutexport
ing it.Base.public_not_exported(m::Module)::Vector{Symbol}
function, which returns the list of all non-exported public names in the modulem
.This feature request is non-breaking. Therefore, it can be implemented in a Julia 1.x release.
Part 1:
Base.@public
macroFor example, suppose that my package has a public function named fit. Because that word is so common, I don't want to export it from my package. But I want to indicate that it is part of the public API in a structured way that downstream tools (Documenter.jl, JuliaHub, editors/IDEs, etc.) can understand.
So in this example, I could do something like the following:
Part 2:
Base.public_not_exported
functionThe signature of the function will be:
Base.public_not_exported(m::Module)::Vector{Symbol}
.Example usage:
Related Discussions
There is some related discussion in JuliaDocs/Documenter.jl#1507. However, I really want this to be something that any tool can use, so I don't want it to be specific to Documenter.
The text was updated successfully, but these errors were encountered: