# Custom Agent constructors?

**URL:** <https://discourse.julialang.org/t/custom-agent-constructors/113376>\
**Category:** Modelling & Simulations\
**Created:** [April 23, 2024, 8:20am UTC](https://discourse.julialang.org/t/custom-agent-constructors/113376 "2024-04-23T08:20:24Z")\
**Posts on this page:** 3\
**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:** [April 23, 2024, 8:20am UTC](https://discourse.julialang.org/t/custom-agent-constructors/113376/1 "2024-04-23T08:20:24Z")

</div>

I’d like to preprocess the parameters that are passed to an Agent upon construction. How would I go about that?

A simple example of what I’d like to do:

```julia
function make_set(t::Union{Nothing, Symbol, Set{Symbol}})
  if t === nothing
    return Set{Symbol}()
  elseif t isa Symbol
    return Set([t])
  else
    return t
  end
end

@agent struct TestAgent(NoSpaceAgent)
   types::Set{Symbol} = make_set(types)
 end
```

But that doesn’t work. The code compiles fine but when I then execute:

```julia
TestAgent(id = 1, types = :test)
```

I get the following error:  
ERROR: MethodError: Cannot `convert` an object of type Symbol to an object of type Set{Symbol}

Closest candidates are:  
convert(::Type{T}, ::T) where T\<:AbstractSet  
@ Base set.jl:550  
convert(::Type{T}, ::T) where T  
@ Base Base.jl:84  
convert(::Type{T}, ::AbstractSet) where T\<:AbstractSet  
@ Base set.jl:551  
…

Is there a solution for this?

Thanks in advance,  
Stef

---

<div class="post-metadata">

**Author:** ![PaoloBova](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paolobova/32/19906_2.png) [@PaoloBova](https://discourse.julialang.org/u/PaoloBova)\
**Post date:** [April 23, 2024, 10:39am UTC](https://discourse.julialang.org/t/custom-agent-constructors/113376/2 "2024-04-23T10:39:59Z")

</div>

Hi Stef.

Unfortunately, I’m not aware of a good way to achieve what you’re looking for. The closest I can manage is creating a helper function which calls your agent constructor as follows:

```julia
TestAgent_helper(; kwargs...) = begin
    types = get(kwargs, :types, nothing)
    TestAgent(; kwargs..., types=make_set(types))
end

```

You can check that the following calls work correctly

```julia
TestAgent_helper(; id=1, types=:test) # types will be Set([:test])
TestAgent_helper(; id=1) # types will be Set{Symbol}()

```

It’s still not clear to me why what you’re after would be desirable. Is there a reason in your use case why processing your `types` data before calling the constructor would be inconvenient? Perhaps there are other ways to address the issues you are facing without adding extra logic into or around the agent constructor.

You didn’t ask for an explanation of the error, but I’ll give one below just in case.

What your code does is set the default value of `types` to be `make_set(types)`  
You get an error because when you pass in a value for `types` it is used instead of the default value, and it is not of the specified type. Your default value would also error if you called the agent constructor without specifying `types` since `types` is not defined anywhere else.

Hope this is useful. Regards,

Paolo

---

<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:** [April 23, 2024, 11:37am UTC](https://discourse.julialang.org/t/custom-agent-constructors/113376/3 "2024-04-23T11:37:43Z")

</div>

The main reason why I want to do this is to make it easier to use the code. Writing

```julia
TestAgent(types = :aType)
```

is just less cumbersome than having to write

```julia
TestAgent(types = Set([:aType]))
```

all the time 😉

Thank you for the explanation. That definitely helps.

Kind regards,  
Stef
