But if I read it correctly 5. is saying that I can read from a global const, which is something we can easily do e.g. in your example I can put const BREAKPOINTS = []
I tried your code in a module, calling foo
doesn’t print anything
What did you try exactly? My code does not contain any prints so would not print anything
ah yeah sorry, just misinterpreted the output…anyway given we can annotate the container with global const
do you think we respect the contract?
No. It reads “non-constant state” and a vector in a constant variable is still mutable state. I think the issue is exactly that the function won’t update/recompile if this mutable state changes and thus Julia does not want to make any promises on consistency. So if we take care of that, I think we might be able to make it work somewhat safely (i.e. the generated function could also set a flag, that it ran and if someone tries to change the dispatch later, we can throw an error).
I found this old package GitHub - toivoh/PatternDispatch.jl: Method dispatch based on pattern matching for Julia, it doesn’t work on Julia 1.x but since it’s basically the same thing I guess it could enlighten us maybe @abraemer
Maybe I found another solution!
Consider this:
julia> module Foo
module SubFoo
const BREAKPOINTS = []
function __init__()
@eval parentmodule(SubFoo) x = SubFoo.BREAKPOINTS[end]
end
end
push!(SubFoo.BREAKPOINTS, 1)
push!(SubFoo.BREAKPOINTS, 3)
push!(SubFoo.BREAKPOINTS, 5)
push!(SubFoo.BREAKPOINTS, 7)
end
Main.Foo
julia> Foo.x
7
This means if I’m not mistaken at the first call of @dispatch
I could generate automatically a module with an __init__()
function which evaluates all the methods in the book-keeping
No I don’t think this would work in practice. AFAIK the __init__
is run as soon as you import
/using
the submodule. When would you do this in a package?
I am not quite sure why this works in the REPL though.
It should actually @abraemer, I tested the exact same code also in a package I dev, where precompilation happened before, same behaviour
the docstring seems to confirm this:
The __init__() function in a module executes immediately after the module is loaded at runtime
for the first time. It is called once, after all other statements in the module have been
executed. Because it is called after fully importing the module, **__init__ functions of
submodules will be executed first**.
Ah yes, I had read that but misinterpreted it. Then it could work!