Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem Using @isdefined Inside a @resumable Function #119

Open
MarkNahabedian opened this issue Dec 6, 2024 · 4 comments
Open

Problem Using @isdefined Inside a @resumable Function #119

MarkNahabedian opened this issue Dec 6, 2024 · 4 comments

Comments

@MarkNahabedian
Copy link

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.
@Krastanov
Copy link
Member

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.

@thofma
Copy link
Collaborator

thofma commented Dec 6, 2024

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.

@Krastanov
Copy link
Member

Indeed, just added it here 3e944f3

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.

@MarkNahabedian
Copy link
Author

MarkNahabedian commented Dec 6, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants