# How to parameterize the name of a struct?

**URL:** <https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623>\
**Category:** General Usage\
**Created:** [January 21, 2020, 3:08pm UTC](https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623 "2020-01-21T15:08:20Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [January 21, 2020, 3:08pm UTC](https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623/1 "2020-01-21T15:08:20Z")

</div>

I would like to define in an automatic way a struct like:

```julia
struct MyStruct
   some_field
end

```

where the struct name “MyStruct” can be read from a string array. I found [https://github.com/cstjean/QuickTypes.jl](https://github.com/cstjean/QuickTypes.jl), but from my understanding this only uses parameterization for the struct fields.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [January 21, 2020, 3:17pm UTC](https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623/2 "2020-01-21T15:17:04Z")

</div>

Like so maybe:

```julia
julia> names = [:A, :B]
2-element Array{Symbol,1}:
 :A
 :B

julia> for n in names
         @eval struct $n
                 some_field
               end
       end

julia> A(1)
A(1)

```

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [January 21, 2020, 3:23pm UTC](https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623/3 "2020-01-21T15:23:03Z")

</div>

To add on this solution:

```julia
julia> names = ["A", "B"]
2-element Array{String,1}:
 "A"
 "B"
julia> for n in names
            s=Symbol(n)
            @eval struct $s
                  some_field
                  end
            end

```

---

<div class="post-metadata">

**Author:** ![Daniel\_Berge](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_Berge](https://discourse.julialang.org/u/Daniel_Berge)\
**Post date:** [January 21, 2020, 3:24pm UTC](https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623/4 "2020-01-21T15:24:54Z")

</div>

Is the name of the `struct` important? Could a `NamedTuple` be of use to you? [Types · The Julia Language](https://docs.julialang.org/en/v1/manual/types/#Named-Tuple-Types-1)

---

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [January 21, 2020, 5:46pm UTC](https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623/5 "2020-01-21T17:46:57Z")

</div>

Many thanks for helping me! @Daniel_Berge, I want to use multiple dispatch in order to call certain methods based on the argument type. To be more specific, I want to write some generic high level wrappers for lab instruments. For example:

```julia
function set_voltage(psu::Agilent, volt = 0)
write(psu.obj, "SpecificAgilentCommand")
end

function set_voltage(psu::Tek, volt = 0)
write(psu.obj, "SpecificTekCommand")
end

```

I know this could be handled easily with if/else, but I want to try a different way.  
“psu” can contain fields like:

```julia
struct psu
   name
   address
   obj
end

```

and the “obj” field can be initialized using [GitHub - BBN-Q/Instruments.jl: Instrument control in Julia](https://github.com/BBN-Q/Instruments.jl) and the “address” field.  
Having multiple types of equipment it becomes cumbersome to hardcode manually all the structs with instruments names, so I wanted a way to auto-generate a struct based on the instrument that I need, in order to specialize a method.  
I think code is much more readable like this and anyone can add a new method for a different instrument easily.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [January 21, 2020, 9:19pm UTC](https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623/6 "2020-01-21T21:19:32Z")

</div>

> [@Iulian.Cioarca](#):
>
> Having multiple types of equipment it becomes cumbersome to hardcode manually all the structs with instruments names, so I wanted a way to auto-generate a struct based on the instrument that I need, in order to specialize a method.

But then you should use a type parameter, on which you can dispatch just as well:

```julia
struct Int{Kind}
  name
  address
  obj
end

f(ins::Inst{:Aglient}) = 1
f(ins::Inst{:Tek}) = 2

```

If you need something instrument specific you can always put that in a field containing a Dict or NamedTuple.

---

<div class="post-metadata">

**Author:** ![KajWiik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kajwiik/32/199_2.png) [@KajWiik](https://discourse.julialang.org/u/KajWiik)\
**Post date:** [January 21, 2020, 10:48pm UTC](https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623/7 "2020-01-21T22:48:44Z")

</div>

> [@mauro3](#):
>
> f(ins::Inst{:Aglient}) = 1

This does not seem to work (Version 1.3.0) (Edit: yes it does, fixed a typo!):

```julia
julia> struct Inst{Kind}
         name
         address
         obj
       end

julia> a=Inst{:Agilent}("foo",2,3)
Inst{:Agilent}("foo", 2, 3)

julia> f(i::Inst{:Agilent}) = 1
f (generic function with 1 method)

julia> f(a)
1

```

---

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [January 21, 2020, 11:01pm UTC](https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623/8 "2020-01-21T23:01:06Z")

</div>

@mauro3, your last solution is even simpler! Thank you!  
@KajWiik, I think there is a typo in your code(Agilent vs Aglient). Your example worked for me in 1.3.1

---

<div class="post-metadata">

**Author:** ![KajWiik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kajwiik/32/199_2.png) [@KajWiik](https://discourse.julialang.org/u/KajWiik)\
**Post date:** [January 21, 2020, 11:07pm UTC](https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623/9 "2020-01-21T23:07:56Z")

</div>

DOH! 😳

---

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [January 21, 2020, 11:20pm UTC](https://discourse.julialang.org/t/how-to-parameterize-the-name-of-a-struct/33623/10 "2020-01-21T23:20:59Z")

</div>

For anyone interested, this is how the code looks so far:

```julia
using Instruments
import Instruments: ResourceManager, GenericInstrument, connect!, disconnect!, write, read, query

mutable struct INSTR{instr_name}
    name
    address
    obj
end
# Generic instrument constructor
INSTR(instr_name, address) = INSTR{instr_name}(instr_name, address, GenericInstrument())

connect!(rm, instr) = connect!(rm, instr.obj, instr.address)
disconnect!(instr) = disconnect!(instr.obj)
disconnect!(rm, instr) = disconnect!(instr.obj)

function set_instr_state!(rm, x...; act = disconnect!)
    for instr in x
        act(rm, instr)
    end
end
function set_volt(psu::INSTR{:Agilent}, volt = 0)
    # write(psu.obj,"some instruction 1")
    println("Agilent was called!")
end
function set_volt(psu::INSTR{:Tek}, volt = 0)
    # write(psu.obj,"some instruction 2")
    println("Tek was called!")
end

# instantiate obj
rm = ResourceManager()
my_psu1 = INSTR(:Agilent, "GPIB0::14::INSTR")
my_psu2 = INSTR(:Tek, "GPIB0::7::INSTR")
set_instr_state!(rm, my_psu1, my_psu2; act = connect!) #this will error if no instruments availale
# USAGE
set_volt(my_psu2)
# Disconnect everything
set_instr_state!(rm, my_psu1, my_psu2)

```

Actual communication not tested yet, but I don’t expect any issues.  
Thank you all, again, for your help!
