Problem Using `@isdefined` Inside a `@resumable` Function
I'm having a problem using @isdefined inside a @resumable
function (https://github.com/JuliaDynamics/ResumableFunctions.jl).
function foo(x)
local y
@isdefined y
end
works, but
@resumable function foo(x)
local y
@isdefined y
end
gets the error
ERROR: LoadError: MethodError: no method matching var"@isdefined"(::LineNumberNode, ::Module, ::Expr)
Closest candidates are:
var"@isdefined"(::LineNumberNode, ::Module, !Matched::Symbol)
@ Base essentials.jl:177
When I try to macroexpand the same definition I get the same error.
@macroexpand @resumable function foo(x) local y y end
The problem appears to be because `@resumable` replaces local
variables in the function body with struct property references:
using MacroTools prewalk(rmlines, @macroexpand @resumable function foo(x) local y y end ) quote mutable struct var"##foo_FSMI#307"{var"##y#308" <: Any, var"##x#309" <: Any} <: ResumableFunctions.FiniteStateMachineIterator{Any} _state::UInt8 y::var"##y#308" x::var"##x#309" function var"##foo_FSMI#307"{var"##y#308", var"##x#309"}(; ) where {var"##y#308" <: Any, var"##x#309" <: Any} fsmi = new() fsmi._state = 0x00 fsmi end function var"##foo_FSMI#307"(; ) var"##foo_FSMI#307"{Any, Any}() end end function (_fsmi::var"##foo_FSMI#307")(_arg::Any = nothing; ) _fsmi._state === 0x00 && $(Expr(:symbolicgoto, :_STATE_0)) error("@resumable function has stopped!") $(Expr(:symboliclabel, :_STATE_0)) _fsmi._state = 0xff _arg isa Exception && throw(_arg) local _fsmi.y _fsmi.y end begin $(Expr(:meta, :doc)) function foo(x::Any; ) fsmi = ResumableFunctions.typed_fsmi(var"##foo_FSMI#307", var"##306", x) fsmi.x = x fsmi end end end
I don't see an obvioous fix for this, but feel it should be noted as
the error message doesn't clearly point to the problem.
Thanks for flagging this!
The @isdefined macro just leaves a flag for the lower (not accessible) levels of julia to deal with it.
julia> @macroexpand @isdefined x
:($(Expr(:isdefined, :x)))
And the isdefined function is a built-in
julia> isdefined
isdefined (built-in function)
Given that ResumableFunctions's premise is to take a function and chop it up and convert it into a finite state machine, this type of Julia built-ins would need to be reimplemented from scratch. If someone wants to give that a try, PRs are welcomed! But I do not believe any of the current maintainers plan to work on this in the future as isdefined for local variables is not something that should be present in most code.
More generally, macros, even less invasive macros than this one, do not work too well in resumable functions from this library. See #54 and #104. These issues might be addressed sooner though.
I don't see how this could be made work with the current approach. I think @isdefined needs to be added to https://github.com/JuliaDynamics/ResumableFunctions.jl?tab=readme-ov-file#caveats.
Indeed, just added it here https://github.com/JuliaDynamics/ResumableFunctions.jl/commit/3e944f36ce57af69a8069a3fea9ead46f734b558
For now I am marking it as wontfix as there isn't anyone I know that plans to tackle it.
I am also marking it as error messages -- as OP mentioned, the error messages related to this can be better.
Thanks for the quick response. I have a workaround using an initial value of nothing.
On Dec 6, 2024 11:21 AM, Stefan Krastanov @.***> wrote:
Indeed, just added it here 3e944f3https://github.com/JuliaDynamics/ResumableFunctions.jl/commit/3e944f36ce57af69a8069a3fea9ead46f734b558
For now I am marking it as wontfix as there isn't anyone I know that plans to tackle it.
I am also marking it as error messages -- as OP mentioned, the error messages related to this can be better.
— Reply to this email directly, view it on GitHubhttps://github.com/JuliaDynamics/ResumableFunctions.jl/issues/119#issuecomment-2523661745, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AIBY3E7OLVGKNKPETURARXD2EHFHVAVCNFSM6AAAAABTETL5XSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKMRTGY3DCNZUGU. You are receiving this because you authored the thread.Message ID: @.***>