Sure is Tuple{1, :foo} valid (but uninhabited).
Yes, that had occurred to me and would clash badly with this syntax idea. It makes much more sense to me for the parameter names of parametric types to be significant by default than for argument names of functions to be significant by default. Writing Array{N=1} for Vector and Array{N=3} for a three-tensor could be handy and general.
In the other direction, supporting more direct syntax for e.g. Units may be worth considering, although theyâve used non-standard string literals to address this already.
The other issue is that ccall doesnât really make sense for arbitrary julia tuple types, and needs to have the types written out in the call â it canât accept an arbitrary tuple-type-valued expression (e.g. ccall(:foo, RT, ArgT, ...)). Reflection functions that take tuple types do though. Given that, thereâs no reason to impose the extra syntactic overhead of Tuple{ } in ccall.
But the same applies to named tuples and llvmcall, right?
llvmcall Iâm not sure about; it could probably use tuples of types as well.
With NamedTuples we also have e.g. NamedTuple{n, T} where T<:Tuple{Any,Any}, the type of 2-element NamedTuples. Basically, we can reuse existing capabilities of the type system. If the second parameter had to be a tuple of types, supporting that alternate representation would leak everywhere in the type system. By next year weâd be debating whether (Int,) == Tuple{Int} ![]()
Yes, a macro is the best option I can see here so far. E.g. @NT(a::Int, b::String).
Handy constructors are also defined in NamedTupleTools