JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.43k stars 5.45k forks source link

Cannot quote `public` statements #51450

Open mbauman opened 11 months ago

mbauman commented 11 months ago

It'd be great if this could work:

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

Found because I was exploring public behaviors interactively and was trying to do something like the below — the equivalent using export works:

julia> @eval Base begin
       foo = 1
       public foo
ERROR: ParseError:
# Error @ REPL[16]:3:8
foo = 1
public foo
#      └─┘ ── Expected `end`
Stacktrace:
 [1] top-level scope
   @ none:1
mbauman commented 11 months ago

Oh, yeah, public exprs print like this should work:

julia> Expr(:public, :foo)
:(public foo)

julia> @eval Base begin
       foo = 1
       $(Expr(:public, :foo))
       end

julia> Base.ispublic(Base, :foo)
true
matthias314 commented 5 months ago

What about adding this issue to the 1.11 milestone? I think it would be strange if 1.11.0 introduced the public construction, but didn't allow it when quoting. If this is added later, then you cannot use it in packages that are also supposed to work with 1.11.0.

LilithHafner commented 4 months ago

FWIW, this was done intentionally. pubilc is only a keyword at toplevel to reduce breakage (b.c. it isn't a keyword in 1.10). We can probably expand that to toplevel + quotes, though.

KristofferC commented 4 months ago

Is there any progress here? Othewise, this doesn't seem really important enough to be on the milestone.

LilithHafner commented 4 months ago

It would be easier to change this parsing behavior after this minor refactoring which I'm waiting for review on.

JamesWrigley commented 1 week ago

Is that why this string fails to parse?

julia> Meta.parse("@static if true public foo end")
ERROR: ParseError:
# Error @ none:1:24
@static if true public foo end
#                      └─┘ ── Expected `end`
Stacktrace:
 [1] #parse#3
   @ ./meta.jl:242 [inlined]
 [2] parse
   @ ./meta.jl:234 [inlined]
 [3] parse(str::String; filename::String, raise::Bool, depwarn::Bool)
   @ Base.Meta ./meta.jl:276
 [4] parse(str::String)
   @ Base.Meta ./meta.jl:274
 [5] top-level scope
   @ REPL[32]:1

Noticed it when I tried to use that expression in a package and it failed to load.

LilithHafner commented 1 week ago

It's related, but no. public is not quoted in that example. Also, FYI, using @static will not help with constructs that parse in only some versions. Contrary to it's docstring in Julia 1.11 and earlier, @static partially evaluates at macro expansion time, not parse time. The whole expression is parsed before @static takes effect. The docstring was fixed in https://github.com/JuliaLang/julia/pull/54206