# Problems with Agent constructors

**URL:** <https://discourse.julialang.org/t/problems-with-agent-constructors/115761>\
**Category:** New to Julia\
**Tags:** agents, agentsjl\
**Created:** [June 17, 2024, 2:30pm UTC](https://discourse.julialang.org/t/problems-with-agent-constructors/115761 "2024-06-17T14:30:13Z")\
**Posts on this page:** 9\
**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:** [June 17, 2024, 2:30pm UTC](https://discourse.julialang.org/t/problems-with-agent-constructors/115761/1 "2024-06-17T14:30:13Z")

</div>

I’m probably not seeing something obvious but for some reason I have one Agent for which the constructor works and another one for which I get an error when I try to call the constructor and I have no clue why.

Here is the code:

```julia
@agent struct Actor(NoSpaceAgent) <: AbstractActor
    types::Set{Symbol} = Set{Symbol}()
    behaviors::Vector{Function} = Vector{Function}()
    properties::D where {D <: Dict{Symbol, <:Any}} = Dict{Symbol, Any}()
end

abstract type BalanceActor{C <: FixedDecimal} <: AbstractActor end

# This one works
@agent struct SuMSyActor{C}(Actor) <: BalanceActor{C}
    model::ABM
    balance::SuMSyBalance
    contribution_settings::Union{SuMSy, Nothing}
    contribution::C = CUR_0
end

# This one does not
@agent struct MonetaryActor{C}(Actor) <: BalanceActor{C}
    model::ABM
    balance::AbstractBalance = Balance()
end
```

This is how I call the constructors:

```julia
# I initialised the necessary variables beforehand

SuMSyActor(model, model = model, balance = balance, contribution_settings = contribution_settings)

MonetaryActor(model, model = model)

#I also tried
MonetaryActor(model, model = model, balance = Balance())
```

The error I get with MonetaryActor is:

```julia
ERROR: MethodError: no method matching MonetaryActor(::Int64, ::Set{…}, ::Vector{…}, ::Dict{…}, ::StandardABM{…}, ::Balance{…})

Closest candidates are:
  MonetaryActor(::AgentBasedModel, ::Any...)
   @ EconoSim ~/.julia/packages/Agents/8JW8b/src/core/agents.jl:217

Stacktrace:
 [1] MonetaryActor(; id::Int64, types::Set{…}, behaviors::Vector{…}, properties::Dict{…}, model::StandardABM{…}, balance::Balance{…})
   @ EconoSim ~/.julia/packages/Agents/8JW8b/src/core/agents.jl:216
 [2] MonetaryActor(m::StandardABM{…}; kwargs::@Kwargs{…})
   @ EconoSim ~/.julia/packages/Agents/8JW8b/src/core/agents.jl:219
 [3] top-level scope
   @ REPL[12]:1
Some type information was truncated. Use `show(err)` to see complete types.
```

What am I missing here?

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [June 17, 2024, 4:02pm UTC](https://discourse.julialang.org/t/problems-with-agent-constructors/115761/2 "2024-06-17T16:02:34Z")

</div>

Can you provide a runnable example? Because it seems strange that `SuMSyActor` works but `MonetaryActor` doesn’t

---

<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:** [June 18, 2024, 7:50am UTC](https://discourse.julialang.org/t/problems-with-agent-constructors/115761/3 "2024-06-18T07:50:48Z")

</div>

Here is compilable code. I really don’t see why the MonetaryActor constructor doesn’t work.

```julia
using Agents
using FixedPointDecimals

Fixed(digits::Integer) = FixedDecimal{Int128, digits}
Currency = Fixed(4)

abstract type AbstractActor <: AbstractAgent end

@agent struct Actor(NoSpaceAgent) <: AbstractActor
    types::Set{Symbol} = Set{Symbol}()
    behaviors::Vector{Function} = Vector{Function}()
    properties::D where {D <: Dict{Symbol, <:Any}} = Dict{Symbol, Any}()
end

abstract type BalanceActor{C <: FixedDecimal} <: AbstractActor end

# This one works
@agent struct SuMSyActor{C}(Actor) <: BalanceActor{C}
    model::ABM
    balance::Integer
    contribution_settings::Union{Integer, Nothing}
    contribution::C = Currency(0)
end

# This one does not
@agent struct MonetaryActor{C}(Actor) <: BalanceActor{C}
    model::ABM
    balance::Integer = 1
end

model1 = ABM(Actor, agent_step! = step!)

SuMSyActor(model1, model = model1, balance = 1, contribution_settings = 2)

model2 = ABM(Actor, agent_step! = step!)

MonetaryActor(model2, model = model2)
```

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [June 18, 2024, 9:05am UTC](https://discourse.julialang.org/t/problems-with-agent-constructors/115761/4 "2024-06-18T09:05:14Z")

</div>

As a quick fix, you can specify the parameter

```julia
julia> MonetaryActor{FixedDecimal}(model2, model = model2)
MonetaryActor{FixedDecimal}(1, Set{Symbol}(), Function[], Dict{Symbol, Any}(), StandardABM with 0 agents of type Actor
 agents container: Dict
 space: nothing (no spatial structure)
 scheduler: fastest, 1)

```

I’m still a little confused on why it doesn’t work but I don’t have time today to investigate it further

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [June 18, 2024, 9:22am UTC](https://discourse.julialang.org/t/problems-with-agent-constructors/115761/5 "2024-06-18T09:22:53Z")

</div>

Ah, sure, it is because you didn’t use any `C` parameter in `MonetaryActor` fields, so there is no constructor which can infer its type by the field values. That’s why you can only construct `MonetaryActor{FixedDecimal}`. So everything is fine.

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [June 18, 2024, 9:23am UTC](https://discourse.julialang.org/t/problems-with-agent-constructors/115761/6 "2024-06-18T09:23:16Z")

</div>

> [@stefkuypers](#):
>
> ```julia
> # This one does not
> @agent struct MonetaryActor{C}(Actor) <: BalanceActor{C}
> model::ABM
> balance::Integer = 1
> end
> 
> ```

It makes sense it shouldn’t work, as the type `C` is not used anywhere in the type body. The macro doesn’t know how to create “instantiators” for this type.

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [June 18, 2024, 9:24am UTC](https://discourse.julialang.org/t/problems-with-agent-constructors/115761/7 "2024-06-18T09:24:07Z")

</div>

If you did

```julia
struct A{C}
a::Float64
end

```

you can’t instantiate `x = A(0.1)`. Which is what the macro tries to create. You’d need to make the explicit `x = A{whatever}(0.1)`. There is no way to deduce `whatever` from inputs as you can see.

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [June 18, 2024, 9:26am UTC](https://discourse.julialang.org/t/problems-with-agent-constructors/115761/8 "2024-06-18T09:26:19Z")

</div>

We happen to respond exactly at the same time the same thing 😆

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [June 18, 2024, 9:34am UTC](https://discourse.julialang.org/t/problems-with-agent-constructors/115761/9 "2024-06-18T09:34:28Z")

</div>

great minds think alike HAH
