Storing non-isbits data in type parameters

This is most likely not a new discovery, but I just realized you can effectively store non-isbits data in type parameters. MWE:

julia> struct Value{T} end

julia> Value(x) = Value{Symbol(repr(x))}();

julia> unwrap(::Value{sym}) where {sym} = eval(Meta.parse(string(sym)));

julia> v = Value([1, 2])
Value{Symbol("[1, 2]")}()

julia> unwrap(v)
2-element Vector{Int64}:
 1
 2

julia> ValueType(x) = Value{Symbol(repr(x))};

julia> foo(::ValueType([1, 2])) = 42;

julia> foo(v)
42

So, if you ever wanted to dispatch on non-isbits values, now you can. Use wisely. :smiling_imp:

3 Likes

In summary, by converting to a Symbol instance, the only non-isbits value allowed as type parameters, in addition to Tuples containing Symbols. Note that this has a freezing effect, making an immutable copy of a mutable instance, which may be more familiar in the context of dictionary keys.

I’m wondering if converting things to Symbols is unsustainable at some point, I don’t know what happens to interned strings in the long run.

1 Like