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?
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))