# How to use a type wrapping a Symbol as a type parameter?

**URL:** https://discourse.julialang.org/t/how-to-use-a-type-wrapping-a-symbol-as-a-type-parameter/19628
**Category:** General Usage
**Created:** [January 14, 2019, 5:03pm UTC](https://discourse.julialang.org/t/how-to-use-a-type-wrapping-a-symbol-as-a-type-parameter/19628 "2019-01-14T17:03:24Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [January 14, 2019, 5:03pm UTC](https://discourse.julialang.org/t/how-to-use-a-type-wrapping-a-symbol-as-a-type-parameter/19628/1 "2019-01-14T17:03:24Z")

</div>

This question has some lengthy background where I explain my understanding of the problem. If you already know how the rules Julia uses for using values inside type parameters you can skip to the end:

* * *

My understanding is that currently in Julia, if you want to use a value in a type parameter, that value must be a bit value satisfying `isbits(v) == true`. If that works, then for instance you can do

```julia
julia> isbits(5)
true

julia> Val(5)
Val{5}()

julia> typeof(Val(5)) == Val{5}
true

```

This also works for types which wrap `isbits` types

```julia
julia> struct MyInt a::Int end

julia> isbits(MyInt(5))
true

julia> Val(MyInt(5))
Val{MyInt(5)}()

```

On the other hand, non bit types can’t be used in type prameters

```julia
julia> isbits("hi")
false

julia> Val("hi")
ERROR: TypeError: in Type, in parameter, expected Type, got String
Stacktrace:
 [1] Val(::String) at ./essentials.jl:728
 [2] top-level scope at none:0

```

an exception to this rule is `Symbol`s which as far as I understand have been special-cased such that they are allowed in type parameters

```julia
julia> isbits(:hi)
false

julia> Val(:hi)
Val{:hi}()

```

However, it seems unlike `isbits` types, I _can’t_ wrap a `Symbol` in another type and have that work in a type parameter:

```julia
julia> struct MySymbol s::Symbol end

julia> Val(MySymbol(:hi))
ERROR: TypeError: in Type, in parameter, expected Type, got MySymbol
Stacktrace:
 [1] Val(::MySymbol) at ./essentials.jl:728
 [2] top-level scope at none:0

```

* * *

**The Actual Question**  
Is there any way for me to tell the compiler that a value of type

```julia
struct MySymbol s::Symbol end

```

is safe to put in a type parameter? Or is the special casing for `Symbol` not replicable at the user / package level?

---

<div class="post-metadata">

### Author: ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)
#### Post date: [January 14, 2019, 6:06pm UTC](https://discourse.julialang.org/t/how-to-use-a-type-wrapping-a-symbol-as-a-type-parameter/19628/2 "2019-01-14T18:06:39Z")

</div>

You may have mixed up the concept of _field_ and _type parameter_.

Your definition `struct MySymbol s::Symbol end` has a field called `s` but no type parameters. If you want to use a type parameter, it would be defined like this:

```nohighlight
julia> struct MySymbol{s} end

julia> Val(MySymbol{:hi})
Val{MySymbol{:hi}}()

```

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [January 14, 2019, 6:08pm UTC](https://discourse.julialang.org/t/how-to-use-a-type-wrapping-a-symbol-as-a-type-parameter/19628/3 "2019-01-14T18:08:56Z")

</div>

> [@chakravala](#):
>
> You’ve mixed up the concept of _field_ and _type parameter_ .

I don’t believe I have.

What I asked was how I can put a `struct` which _wraps_ a `Symbol` into a type parameter. Not how I can put a symbol in a type parameter.

Notice that

```julia
julia> struct MyInt a::Int end

julia> isbits(MyInt(5))
true

julia> Val(MyInt(5))
Val{MyInt(5)}()

```

works fine. I want to do the analogous operation with a struct that wraps a `Symbol`.

I know that I can put the symbol in the type parameter of `MySymbol` but that wasn’t what I wanted.

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [January 14, 2019, 9:55pm UTC](https://discourse.julialang.org/t/how-to-use-a-type-wrapping-a-symbol-as-a-type-parameter/19628/4 "2019-01-14T21:55:03Z")

</div>

Yeah, this is an interesting question. As far as I know, you can’t do what you’re asking for, and `Symbol` is a bit special in this way. If you were allowed to do this, it would probably have some surprising results, since `Bar{foo1}` would presumably only be the same type as `Bar{foo2}` if `foo1 === foo2` (not simply if `foo1 == foo2`), so you would have:

```julia
s = :hello
s === s # true

```

but non-bitstypes have their own identities, so `Foo(s) !== Foo(s)` and thus `Bar{Foo(s)} !== Bar{Foo(s)}` and also `Bar{Foo(s)} !<: Bar{Foo(s)}`. That would be somewhat awkward.

---

<div class="post-metadata">

### Author: ![tkluck](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkluck/32/15769_2.png) [@tkluck](https://discourse.julialang.org/u/tkluck)
#### Post date: [January 14, 2019, 10:10pm UTC](https://discourse.julialang.org/t/how-to-use-a-type-wrapping-a-symbol-as-a-type-parameter/19628/5 "2019-01-14T22:10:01Z")

</div>

Some relevant experiments related to object identity:

```julia
julia> struct Foo; a::Symbol; end
julia> isbitstype(Foo)
false
julia> Foo(:hello) === Foo(:hello)
true
julia> mutable struct Bar; a::Symbol; end
julia> isbitstype(Bar)
false
julia> Bar(:hello) === Bar(:hello)
false

```

I understand OP’s point as saying that because `Foo` objects don’t have identity, there should be no reason they couldn’t appear in a type parameter. I would agree.

FWIW, tuples of symbols _can_ appear as type parameters (and I use that a lot in my package [GitHub - tkluck/PolynomialRings.jl: A library for arithmetic and algebra with multi-variable polynomials.](https://github.com/tkluck/PolynomialRings.jl)):

```julia
julia> Val((:x, :y, :z))
Val{(:x, :y, :z)}()

```

---

<div class="post-metadata">

### Author: ![jekbradbury](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jekbradbury/32/953_2.png) [@jekbradbury](https://discourse.julialang.org/u/jekbradbury)
#### Post date: [January 15, 2019, 5:06am UTC](https://discourse.julialang.org/t/how-to-use-a-type-wrapping-a-symbol-as-a-type-parameter/19628/6 "2019-01-15T05:06:54Z")

</div>

The relevant check appears to be [this runtime function](https://github.com/JuliaLang/julia/blob/7772486a6942c9a9b52849b6ffe690a7da5861cd/src/builtins.c#L825-L843):

```julia
static int valid_type_param(jl_value_t *v)
{
    if (jl_is_tuple(v)) {
        // NOTE: tuples of symbols are not currently bits types, but have been
        // allowed as type parameters. this is a bit ugly.
        jl_value_t *tt = jl_typeof(v);
        size_t i, l = jl_nparams(tt);
        for(i=0; i < l; i++) {
            jl_value_t *pi = jl_tparam(tt,i);
            if (!(pi == (jl_value_t*)jl_sym_type || jl_isbits(pi)))
                return 0;
        }
        return 1;
    }
    if (jl_is_vararg_type(v))
        return 0;
    // TODO: maybe more things
    return jl_is_type(v) || jl_is_typevar(v) || jl_is_symbol(v) || jl_isbits(jl_typeof(v));
}

```

I wonder if you could just add stuff there…

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [January 15, 2019, 5:33am UTC](https://discourse.julialang.org/t/how-to-use-a-type-wrapping-a-symbol-as-a-type-parameter/19628/7 "2019-01-15T05:33:13Z")

</div>

Would Julia need to be rebuilt if this was modified?

---

<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: [January 15, 2019, 7:02am UTC](https://discourse.julialang.org/t/how-to-use-a-type-wrapping-a-symbol-as-a-type-parameter/19628/8 "2019-01-15T07:02:21Z")

</div>

Yes, of course, it is a C function so you would need to run `make`.
