# Define a type on the fly

**URL:** <https://discourse.julialang.org/t/define-a-type-on-the-fly/15148>\
**Category:** General Usage\
**Tags:** question, metaprogramming\
**Created:** [September 18, 2018, 8:58pm UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148 "2018-09-18T20:58:12Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [September 18, 2018, 8:58pm UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/1 "2018-09-18T20:58:12Z")

</div>

Meta programming gurus, how can I create a `struct` from two `Symbol`s?

So say I have two arrays of symbols, and I want to create types (and set their abstract type) from all their possible combinations, it would look kind of (but not quite) like this:

```julia
abstract type AbstractType end
for x in [:A, :B], y in [:Y, :Z]
    struct $x$y <: AbstractType end
end

```

and the result would mean that the following would be defined:

```julia
struct AY <: AbstractType end
struct AZ <: AbstractType end
struct BY <: AbstractType end
struct BZ <: AbstractType end

```

---

<div class="post-metadata">

**Author:** ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)\
**Post date:** [September 19, 2018, 1:05am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/2 "2018-09-19T01:05:06Z")

</div>

eval a quoted expression.  
Symbols can by combined using the Symbol function.

```julia
x = :A 
y = :B
ToInheritFrom = :Any

eval(:(struct $(Symbol(x,y)) <: $ToInheritFrom end))

```

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [September 19, 2018, 1:07am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/3 "2018-09-19T01:07:03Z")

</div>

What are you trying to do? There’s quite possibly a better way to go about this.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [September 19, 2018, 1:07am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/4 "2018-09-19T01:07:05Z")

</div>

What are you trying to do? There’s quite possibly a better way to go about this.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [September 19, 2018, 6:17am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/5 "2018-09-19T06:17:28Z")

</div>

> [@dpsanders](#):
>
> What are you trying to do? There’s quite possibly a better way to go about this.

I suspect you are right. I have a bunch of factors and these have discrete levels. Like `Food`: `fruit`, `meat`, `bread`… I want to create methods that dispatch on distinct setups, unique collections of factors-level pairs. For that I need to code the factors and their levels as types. I think…

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 19, 2018, 6:39am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/6 "2018-09-19T06:39:26Z")

</div>

> [@yakir12](#):
>
> dispatch on distinct setups, unique collections of factors-level pairs

Consider using named tuples. You can also dispatch on them.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [September 19, 2018, 7:17am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/7 "2018-09-19T07:17:06Z")

</div>

> [@Tamas\_Papp](#):
>
> named tuples

This looks very promising indeed. Fits right in. But how would I build a `NamedTuple` “on the fly”? Say I have a `Dict` where the keys are to be the names in the `NamedTuple` and the values the values. How can I construct a `NamedTuple` out of that…?

```julia
ps = Dict(:k1 => :v1, :k2 => :v2)
(ps...) # doesn't work

```

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [September 19, 2018, 7:21am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/8 "2018-09-19T07:21:44Z")

</div>

> [@yakir12](#):
>
> how would I build a `NamedTuple` “on the fly”?

Never mind, reading the docs helps:

```julia
NamedTuple{tuple(keys(ps)...)}(tuple(values(ps)...))

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 19, 2018, 7:43am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/9 "2018-09-19T07:43:30Z")

</div>

You may find

> **[GitHub - tpapp/EponymTuples.jl: Julia package for deconstructing dispatch on...](https://github.com/tpapp/EponymTuples.jl/)**
>
> Julia package for deconstructing dispatch on NamedTuples. - GitHub - tpapp/EponymTuples.jl: Julia package for deconstructing dispatch on NamedTuples.

helpful.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [September 19, 2018, 7:47am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/10 "2018-09-19T07:47:06Z")

</div>

Wah, I’m sure. Right now I don’t “get it”, but maybe once I start writing the methods for my named tuples I’ll understand EponymTuples better.

Thanks @Tamas_Papp !

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [September 19, 2018, 8:00am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/11 "2018-09-19T08:00:39Z")

</div>

Wait a minute, the dispatch is matched on the actual names and _only the types_ of the values for `NamedTuple`s, _not the actual values_ of the values…

So a function that only accepts `a` will also accept `b`, cause the type signatures will be identical for both `a` and `b`:

```julia
a = (:food = :apple, :container = :box)
b = (:food = :meat, :container = :can)

```

Am I missing something? If that is the case then I’ll need to think this over. All my factor names (i.e. the name part of the named tuple) are always the same. It’s the specific level (i.e. the value part of the named tuple) that changes… It’s the level I want to dispatch on.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 19, 2018, 8:06am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/12 "2018-09-19T08:06:35Z")

</div>

> [@yakir12](#):
>
> Am I missing something?

Possibly, as

1. `a` and `b` above have the same type (check with `typeof`),
2. forms like `EponymTuples.@eponymargs(a, b::Int)` allow you to dispatch on the type of fields.

This package facilitates a programming style I am experimenting with, but is by no means necessary for dispatching on named tuples.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [September 19, 2018, 8:20am UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/13 "2018-09-19T08:20:11Z")

</div>

I could switch the names with the values (and ditch the values, which were the factor names before):

```julia
julia> a = (apple = nothing, box = nothing)
(apple = nothing, box = nothing)

julia> b = (meat = nothing, can = nothing)
(meat = nothing, can = nothing)

julia> typeof(a) ≠ typeof(b)
true

```

But feels like I’m abusing named tuples to get dispatch specifying on values…?

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [September 19, 2018, 12:41pm UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/14 "2018-09-19T12:41:43Z")

</div>

How about creating types Apple() etc and dispatching on combinations of those (if that’s really what you need to do)?

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [September 19, 2018, 12:43pm UTC](https://discourse.julialang.org/t/define-a-type-on-the-fly/15148/15 "2018-09-19T12:43:30Z")

</div>

yea, that was my first line of thought, creating tons of singletons, one per level. But I wish there was a macro for that…
