Instantiation of Tuple with value type parameters

Hi there,

I would like to be able to instantiate Tuples with value type parameters, e.g.

foo = Tuple{3,4}()

that is, similarly to how Val does it

bar = Val(3)


baz = Val{3}()

I was wondering whether there was way to achieve this.

Any pointers would be much appreciated! Thanks!

I am not sure I understand what you are trying to do, but 3,4 are not valid type parameters for Tuple — you need types. So as written, the above is impossible.

Tuple{Val{3},Val{4}} would be a valid type, but there are no general constructors to give you an instance of a Tuple.

Hi Tamas,

First of, thanks for looking into this. Here is another way to put it… On the one hand, I can do define a type like this

struct Foo{T} end

and instantiate it with Tuple{3,4} as type parameter


and this works fine.

On the other hand, and for what I’m trying to do, it would be more convenient to have the type Foo to have a field of type T, that is

struct Foo{T}

but if I can not create instantiate objects of type Tuple{3,4} this won’t work…

Please let me know if that still does not make sense… Thanks again!

This is not possible, as there are no values which have type Tuple{3,4}.

I am still not sure I understand the context though. How is a parametric type which is technically invalid useful for you?

Is there a reason why that’s not possible (i.e. to create values with Tuple{3,4} type)?

The use is similar to how StaticArrays passes Tuple{3,4} as size parameters, with “size” info sometimes statically-typed if I want it,

sfoo = Foo(Tuple{3,4}())

or not

sfoo = Foo((3,4))

Yes — there is no value that has type 3. Eg

julia> (1,2) isa Tuple{Int,Int} 

but for what x would x isa Tuple{3,4} hold?

You can use type parameters like this, but no fields can have this type.

I guess I don’t see why this

julia> Val(3) isa Val{3}

would be possible, but not

julia> Tuple{3,4}() isa Tuple{3,4}

e.g. to hold more than one value with wrapping the whole thing in a tuple.

Is there a fundamental difference, or is it technically not possible?

Thanks again!

You did not wrap anything in a tuple. That is done by Val{(3,4)} and that’s totally fine.

The two has nothing to do with each other. You are trying to construct an instance so you need to figure out what you are trying to construct. The type parameters in each type have their specific meaning. For Val it’s unused and for Tuple it has to be types.

1 Like

I think you may be confused because Val(x) is a shorthand constructor for Val{x}(), which is itself a constructor for a singleton type.

You could define something similar as

struct Foo{T} end
@inline Foo(T) = Foo{T}()

if that’s what you want.

The way I see it, Tuple{3,4} is also a singleton type, and therefore I expected

julia> x = Tuple{3,4}()

to just work. If it were possible, then any number of parameters could be passed without needed to be wrapped as in @yuyichao’s suggestion (Val((3,4))), which I thought would be pretty neat.


For none if no instance of the singleton type Tuple{3,4} can’t be created…

Well, that’s not the definition of a singleton type in julia. A singleton type in julia is a type that has only one instance (i.e. no field). Based on the definition of the Tuple type, a Tuple{3,4} is a type with a field of value 3 and a field of value 4. That’s just invalid.

Of course you may say that field of invalid type is not a field but making this kind of argument for corner cases isn’t what a language should do. There’s simply no reason to allow it. In fact, even Tuple{3,4} should have been an error since it’s not really a valid type. It is only allowed because some package was using it before people realized.

And there, that conflicts with the definition of singleton type.


Ok that is starting to makes sense to me, thanks.

So if I understand correctly, the Tuple{Val{3},Val{4}} type is valid julia, just like Val{(3,4)} whereas Tuple{3,4} is tolerated for backward compatibility issues?

Thanks again!


Backward compatibility and also the fact that this is the only way to put variable number of type parameters in so the use for it might not have been easily replacable. (I didn’t read the discussion too carefully when it came up a while ago)


Got it, thanks a lot!