Are modules intended to work as type parameters?

Currently these are documented as valid type parameters:

Both abstract and concrete types can be parameterized by other types. They can also be parameterized by symbols, by values of any type for which isbits returns true (essentially, things like numbers and bools that are stored like C types or struct s with no pointers to other objects), and also by tuples thereof.

That is seemingly equivalent to this check:

function validparameter(x)
  x isa Type || x isa Symbol || isbits(x) ||
  # () isbits so don't need isempty check
  (x isa Tuple && all(y -> (y isa Symbol || isbits(y)), x))
end

and some examples:

julia> validparameter.([Int :num () (:num, ()) (Int, Int) "num" Base])
1×7 BitMatrix:
 1  1  1  1  0  0  0

Which mostly behave as expected when attempting to use as type parameters:

julia> Val.([Int :num () (:num, ())])
1×4 Matrix{Val}:
 Val{Int64}()  Val{:num}()  Val{()}()  Val{(:num, ())}()

julia> Val((Int, Int))
ERROR: TypeError: in Type, in parameter, expected Type, got a value of type Tuple{DataType, DataType}
...
julia> Val("num")
ERROR: TypeError: in Type, in parameter, expected Type, got a value of type String
...

Except for the module:

julia> Val(Base)
Val{Base}()

It’s useful for dispatch, but is this intentional and stable?

1 Like

Feature added in this PR:

Relevant doc issue on Github bug tracker:

3 Likes

That was a record-fast solution for me. Could not Google that out for my life.

1 Like