-
-
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
Add public keyword #50105
Add public keyword #50105
Conversation
Hard agree on that! It's the same reason I opened an issue instead of a PR directly - I don't know a lick of scheme. |
Very nice prototype! I think storing a scoped flag with each binding is the right semantics and we should do it. For syntax I think there's two obvious options. One would be "properties on
This is a little bit annoying to parse because module paths in the export list parse differently from normal Julia code. But I think we could use the presence of the The good thing about this syntax is it generalizes nicely if we want to add other properties to exported symbols. For example, @dalum mentioned marking experimental API in #49973 (comment) and with this syntax we can have
The other obvious option is a contextual keyword
IMO this reads really nicely - it's telling that it's the title of the PR! - and it matches with constructs such as |
This is really lovely! Thanks for making it ❤️ An argument for the |
are there any other examples of kwarg flags for syntax in the language? If not then a contextual keyword seems more consistent to me after all, it's |
FWIW, I think this name is not very good. It is very unclear what "scoped export" means. The definition of Imo, it should be called some new adjective ( |
Re how else to expose this information, one point I can't find mentioned is tab completion. At present |
Public sounds like a good name. Would the syntax be like this? module Foo
export BAR
public foo, Baz
"adds one"
foo(x) = x+BAR
const BAR = 1
struct Baz end
end Making |
Could also be |
|
This is the adjective used to describe the feature here everywhere though. Yes, there is some baggage from the term in other (OO) languages but I am not sure that is a dealbreaker. But it could be |
(Edit, to clarify: public here means "public use", public in the OO world is "public access", but in both cases, who the "public" is, is kinda the same thing) |
If we have the option to reduce confusion for users coming from other contexts by simply calling it differently, why not do that? We don't have access modifiers and we can't get them until we make a breaking change. I really don't think it's worth having to answer questions like "Does julia have Is it really that absurd to think of people that aren't already using julia and try to accomodate them at least a little bit? |
Of course not, I don't think anyone has indicated that something like that is absurd. It's a balancing act. Using the word that seems to be what we use to describe the feature gives it plus points, the fact that it can be confusing for people coming from another language gives it minus points. Other suggestions might come out on top. |
Here's a list of alternatives to "public" as an adjective from a thesaurus:
I kinda like |
I kinda like |
I like verbs over adjectives; |
The only thing I see reasonable from the lists above is |
One issue with a new "public" keyword is whether it's obvious that exported names are already included (which seems desirable). In the example just above it might be surprising that you do not write export BAR
public BAR, foo, Baz One possibly crazy idea is this: The symbols after export BAR
!export foo, Baz |
I think they'd be considered just as special in the
Or maybe something like
Lowering (or This is what I mean when I say the parsing of this would be forward compatible: it's a one-off change to the syntax and parser to support any number of future properties as needed. |
This is the current definition of However the verb "export" has a much broader meaning in English (https://en.wiktionary.org/wiki/export#Verb) and it's good to go back to the roots of the word to decide whether attaching adverbs to it make sense. In this case I think it's fine. |
What is the reason to piggyback on
Which of those were you particularly thinking about that makes sense to use in the context here of denoting something as public API? |
triage generally likes this but thinks that it should be named |
I'd like to add that triage was not unanimous about calling it |
Returning these things from |
I think that many existing uses of export should stay as is, referring to both full exports and scoped exports. For example, I think it would be reasonable for For referring to unscoped exports, I think the phrase "full export" is reasonable.
It makes it clear that export automatically marks things as public. (I'm also fine with public or whatever; I care 3x that this exists and 1x what it's called) |
As a data point, in pluto, |
We ran PkgEval to try to detect this sort of thing, and it came up with no real failures. However, I see that PkgEval skips Pluto.jl, so we quite plausibly could have missed that. I searched for uses of function completions_exported(cs::Vector{<:Completion})
completed_modules = (c.parent for c in cs if c isa ModuleCompletion)
completed_modules_exports = Dict(m => string.(names(m, all=is_pluto_workspace(m), imported=true)) for m in completed_modules)
map(cs) do c
if c isa ModuleCompletion
c.mod ∈ completed_modules_exports[c.parent]
else
true
end
end
end Which appears to be gatekeeping autocompletion based on whether or not a symbol is in 2: ...
old_names = names(old_workspace, all=true, imported=true)
... Which this PR does not affect the behavior of at all ( @Pangoraw, was that a hypothetical failure, or can you point out the specific error that you are seeing in Pluto? |
As you pointed out, these two instances should be ok (or improved!). There is actually a third one which is used to re-run cells when |
IIUC that will result in increased runtime in an edge case, but not cause errors. Unfortunate, but neither dire nor difficult to fix. IMO that is worth pointing out (thank you for sharing), but not grounds to revert the minor behavior change to |
Co-authored-by: Claire Foster <[email protected]>
News: #51322 |
See JuliaLang/julia#50105 (comment) for context
See JuliaLang/julia#50105 (comment) for context
* Filter on exported symbols in 1.11 See JuliaLang/julia#50105 (comment) for context * Update PlutoRunner.jl
Fixes #52472, which was caused by `names` being changed to also return public, unexported symbols in #50105. Note that this restores previous behavior. A case could be made to instead add the public, unexported bindings as suggestions with the appropriate qualification. Not entirely sure how to test this so I'd welcome any suggestions. --------- Co-authored-by: Jameson Nash <[email protected]>
NOTE: This PR is not a complete solution to the "public interfaces are typically not well specified in Julia" problem. We would need to implement much than this to get to that point. Work on that problem is ongoing in Base and packages and contributions are welcome.
This PR is extended by JuliaLang/Pkg.jl#3511 which defines the semantic interpretation of scoped export and should be merged or closed simultaneously.This adds a mechanism for "scoped export", which marks a symbol as part of the public API without loading it into the global namespace on
using
.Goals
first three goals originally posted by @dalum in #49973 (comment)
Changes this PR makes to achieve those goals
public, list, of, names
names(Module)
reports all public names (including exports)Base.isinternal(::Module, ::Symbol)
is an internal method which determines if a symbol is internal.?my_symbol
flags the docstrings of unexported symbols as internal.Adoption
help?>
mode.@public
so folks can adopt this without dropping support for earlier versions of Julia.TODO
export (scoped-true), list, of, names
. This should be bikeshed and then implemented using JuliaSyntax.jl because @c42f says it's landing soon and I'd rather work with that than the scheme parser. [current syntax:public list, of, names
]Need to mark as public all symbols in Stdlib that are mentioned in the documentation[this can be deferred to another PR before 1.11 lands because the docstring note is milder now].Only tab-complete to public methods. (@mcabbott's suggestions)moved to Only tabcomplete public methods #50717public
rather thanexport scoped=true
.Move the changes in Document how public API is defined (depends on scoped export) Pkg.jl#3511 to here.This implements #38162. See also:
Base.@public
macro for declaring a public name without needing toexport
it #42117