# A question about closures

**URL:** <https://discourse.julialang.org/t/a-question-about-closures/55325>\
**Category:** New to Julia\
**Tags:** closure\
**Created:** [February 15, 2021, 3:38pm UTC](https://discourse.julialang.org/t/a-question-about-closures/55325 "2021-02-15T15:38:52Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![stefkuypers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefkuypers/32/19185_2.png) [@stefkuypers](https://discourse.julialang.org/u/stefkuypers)\
**Post date:** [February 15, 2021, 3:38pm UTC](https://discourse.julialang.org/t/a-question-about-closures/55325/1 "2021-02-15T15:38:52Z")

</div>

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:

```julia
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:

```julia
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

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 15, 2021, 3:44pm UTC](https://discourse.julialang.org/t/a-question-about-closures/55325/2 "2021-02-15T15:44:34Z")

</div>

> [@stefkuypers](#):
>
> `ERROR: UndefVarError: agent not defined`

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?

---

<div class="post-metadata">

**Author:** ![stefkuypers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefkuypers/32/19185_2.png) [@stefkuypers](https://discourse.julialang.org/u/stefkuypers)\
**Post date:** [February 15, 2021, 4:00pm UTC](https://discourse.julialang.org/t/a-question-about-closures/55325/3 "2021-02-15T16:00:17Z")

</div>

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

```julia
condition(1)

```

would translate into

```julia
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

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [February 15, 2021, 4:08pm UTC](https://discourse.julialang.org/t/a-question-about-closures/55325/4 "2021-02-15T16:08:14Z")

</div>

> [@stefkuypers](#):
>
> `condition = state -> has_state(agent, state)`

```julia
function makeCondition(agent) 
  state -> has_state(agent, state)
end
condition = makeCondition(valueToCaptureAsAgentInClosure)

```

---

<div class="post-metadata">

**Author:** ![stefkuypers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefkuypers/32/19185_2.png) [@stefkuypers](https://discourse.julialang.org/u/stefkuypers)\
**Post date:** [February 15, 2021, 4:22pm UTC](https://discourse.julialang.org/t/a-question-about-closures/55325/5 "2021-02-15T16:22:35Z")

</div>

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:

```julia
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

```

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [February 15, 2021, 5:02pm UTC](https://discourse.julialang.org/t/a-question-about-closures/55325/6 "2021-02-15T17:02:57Z")

</div>

It sounds like you’d rather have the closure enclose the state, not the agent. Perhaps

```julia
condition(state) = agent -> has_state(agent, state)
random_agent(model, condition(1))

```

---

<div class="post-metadata">

**Author:** ![stefkuypers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefkuypers/32/19185_2.png) [@stefkuypers](https://discourse.julialang.org/u/stefkuypers)\
**Post date:** [February 15, 2021, 5:06pm UTC](https://discourse.julialang.org/t/a-question-about-closures/55325/7 "2021-02-15T17:06:41Z")

</div>

Yes! That works! Thanks!
