Hi,
I’m trying to work out how to construct a closure for the following case:
The Agents package has a random_agent(agent, condition) function and I want to call it with a condition closure. I though the following would work:
using Agents
mutable struct MyAgent <: AbstractAgent
id::Int64
state::Int64
end
has_state(agent, state) = agent.state == state
model = ABM(MyAgent)
add_agent!(MyAgent(1, 1), model)
add_agent!(MyAgent(2, 1), model)
condition = state -> has_state(agent, state)
random_agent(model, condition(1))
But then I get the following error:
ERROR: UndefVarError: agent not defined
Stacktrace:
[1] (::var"#7#8")(::Int64) at ./none:1
[2] top-level scope at none:1
What am I doing wrong?
Thanks in advance,
Stef
You haven’t defined any variable named agent
for the closure to capture. What do you expect agent
to refer to in your condition
closure?
1 Like
I’m pretty new to working with closures so this was my reasoning:
random_agent() calls condition(agent)
I need to pass the a state to the condition function.
If I use a closure I can pretend the state in the function call.
So my expectation was that
condition(1)
would translate into
condition(agent, state = 1)
where agent would be bound in the random_agent() function.
But apparently that’s not the way it works
So, how do I make it work?
Thanks in advance,
Stef
function makeCondition(agent)
state -> has_state(agent, state)
end
condition = makeCondition(valueToCaptureAsAgentInClosure)
I don’t see how that solves the problem. I don’t know which agent will be passed to the condition() function since the random_agent() function supplies the agent. I need to supply the state.
But maybe I’m missing something.
I tried passing the condition to the random_agent() function as makeCondition(1) but then I get the following error:
ERROR: type Int64 has no field state
Stacktrace:
[1] getproperty(::Int64, ::Symbol) at ./Base.jl:33
[2] has_state(::Int64, ::MyAgent) at ./none:1
[3] (::var"#9#10"{Int64})(::MyAgent) at ./none:2
[4] random_agent(::AgentBasedModel{Nothing,MyAgent,typeof(fastest),Nothing}, ::var"#9#10"{Int64}) at /Users/stef/.julia/packages/Agents/VKc78/src/core/model.jl:173
[5] top-level scope at none:1
It sounds like you’d rather have the closure enclose the state, not the agent. Perhaps
condition(state) = agent -> has_state(agent, state)
random_agent(model, condition(1))
3 Likes