johnnychen94 / LazyModules.jl

No, no, not now
MIT License
21 stars 2 forks source link

macro calling twice a function to solve world age issues #9

Closed CarloLucibello closed 2 years ago

CarloLucibello commented 2 years ago

In order to solve the world-age issue

julia> using LazyModules

julia> @lazy import ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534"
LazyModule(ImageCore)

julia> function foo()
           c = ImageCore.RGB(0.0, 0.0, 0.0)
           return c .* 3
       end
foo (generic function with 1 method)

julia> foo()
ERROR: MethodError: no method matching length(::ColorTypes.RGB{Float64})
The applicable method may be too new: running in world age 31343, while current world is 31370.
...

julia> foo()
RGB{Float64}(0.0,0.0,0.0)

I wonder if we can introduce a macro to call the function twice:

@lazy ImageCore function foo()
    c = ImageCore.RGB(0.0, 0.0, 0.0)
    return c .* 3
end

expanding to

function foo()
    if is_not_imported_already(ImageCore)
        do_the_import(ImageCore)
        return foo()
    end
    c = ImageCore.RGB(0.0, 0.0, 0.0)
    return c .* 3
end
CarloLucibello commented 2 years ago

unfortunately, this approach doesn't really work:

julia> using LazyModules

julia> @lazy import ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534"
LazyModule(ImageCore)

julia> function foo()
           if !ImageCore._lazy_loaded
               LazyModules.checked_import(ImageCore)
               return foo()
           end
           c = ImageCore.RGB(0.0, 0.0, 0.0)
           return c .* 3
       end
foo (generic function with 1 method)

julia> foo()
ERROR: MethodError: no method matching ColorTypes.RGB(::Float64, ::Float64, ::Float64)
The applicable method may be too new: running in world age 31334, while current world is 31363.
Closest candidates are:
  ColorTypes.RGB(::T, ::T, ::T) where T<:Union{AbstractFloat, FixedPointNumbers.FixedPoint} at ~/.julia/packages/ColorTypes/1dGw6/src/types.jl:108 (method too new to be called from this world context.)
  ColorTypes.RGB(::Real, ::Real, ::Real) at ~/.julia/packages/ColorTypes/1dGw6/src/types.jl:461 (method too new to be called from this world context.)
  ColorTypes.RGB(::Union{Real, ColorTypes.AbstractGray}, ::Union{Real, ColorTypes.AbstractGray}, ::Union{Real, ColorTypes.AbstractGray}) at ~/.julia/packages/ColorTypes/1dGw6/src/types.jl:603 (method too new to be called from this world context.)
  ...
Stacktrace:
 [1] foo()
   @ Main ./REPL[4]:6
 [2] foo()
   @ Main ./REPL[4]:4
 [3] top-level scope
   @ REPL[5]:1

Maybe @timholy has a solution?

johnnychen94 commented 2 years ago

We recently wrote some documentation to explain this, https://juliaio.github.io/FileIO.jl/dev/world_age_issue/ IIUC, there's no trivial solution that applies to all scenarios.