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.
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.
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.
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.
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?
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)