Roger-luo / Configurations.jl

Options & Configurations made easy.
https://configurations.rogerluo.dev/stable
MIT License
80 stars 12 forks source link

@static if inside @option #39

Closed fonsp closed 3 years ago

fonsp commented 3 years ago

While trying to port Pluto to Configurations.jl, I found this:

julia> using Configurations

julia> f() = 123
f (generic function with 1 method)

julia> @option struct A
           x=f()
       end

julia> @option struct B
           x=1
           @static if true
               y=f()
           end
       end

julia> A()
A(;
)

julia> A(1)
A(;
    x = 1,
)

julia> B()
ERROR: MethodError: no method matching B(::Int64)
Closest candidates are:
  B(; x) at none:0
Stacktrace:
 [1] B(; x::Int64)
   @ Main ./none:0
 [2] B()
   @ Main ./none:0
 [3] top-level scope
   @ REPL[9]:1

julia> B(1,2)
ERROR: MethodError: no method matching B(::Int64, ::Int64)
Stacktrace:
 [1] top-level scope
   @ REPL[5]:1

We use @static here: https://github.com/fonsp/Pluto.jl/blob/main/src/Configuration.jl#L84

Roger-luo commented 3 years ago

I think this raises the question of whether we should macroexpand the struct body before feeding the expression into option codegens, the answer is probably a no since it's very likely that one wants to use a macro to further extend the syntax inside a JLKwStruct syntax, e.g I did this to support custom validation in https://github.com/Roger-luo/KungIChi.jl

So I think the solution is probably only special case the @static macro. I need to think about this a bit.

Roger-luo commented 3 years ago

OK I think we should do macroexpand for @option since @option aims to be the same with Base.@kwdef but the macroexpand only happens in option_m thus whoever do not want macroexpand can still use Configurations' advance codegen feature to implement their own compatible option types.