where
clauses can constrain type parameters that are types e.g. where T <: Number
, but I’m interested in constraining instances e.g. where T isa Symbol
vs. where T isa Integer
, which is not valid syntax. Is there a way to do that? I know I can work around it, but I wonder if there’s a clean way to use the typical multimethod dispatch.
what do you want to do with this?
No use case in mind, but dispatching to different methods depending on different constraints:
f(x::Val{S}) where S isa Symbol = Symbol(S, :v2)
f(x::Val{N}) where N isa Integer = N + 1
you’re taking detours for no reason:
julia> f(x::Symbol) = Symbol(x, :v2)
f (generic function with 2 methods)
julia> f(:bb)
:bbv2
julia> f(N::Integer) = N + 1
f (generic function with 3 methods)
julia> f(2)
3
in general, Julia does not like dispatch-by-value, nor does it support computed types, see GitHub - vtjnash/ComputedFieldTypes.jl: Build types in Julia where some fields have computed types FYI
Well, yes, but as I said, I didn’t have a use case in mind. The right-hand expressions were unimportant, that was just a minimal example of the where
clauses I have in mind. I also am not interested in arbitrarily computing types in annotations or where
clauses (I think I can use methods to accomplish similar things). isa
just seems like a natural complement to <:
for constraining type parameters, which can be either instances or types. Without it, the workaround for that example is:
f2(x::Val{T}) where T = f(T)
f(S::Symbol) = Symbol(S, :v2)
f(N::Integer) = N + 1
You are right about it not being idiomatic. Besides where
-isa
not being supported, I cannot think of any commonly used type parameter that is implemented as an instance of >1 type. For example, there’s no such thing as a Array{Int, :one}
; N isa Int
.
In general, no. where
operates not on types or values directly, but TypeVar
s - you can think of them as a placeholder for types (and isbits
values, but those don’t have computation defined in this context) and as a tool to communicate with the specialization mechanism of the compiler.
In type-speak, julia’s dispatch/parametrization/types generally does not have dependent types (save for the isbits
stuff, but as you can’t compute in where
with those, only in the function itself, it’s not quite there for fully dependent typing).
I don’t understand the type-speak stuff, but it does make sense that where
isn’t working on types and values directly, so something like an isa
isn’t possible. This question popped into my head because of the last two points in this comment; it was possible to jerry-rig a type-stability optimization by annotating a parametric method’s return type, but it seemed more natural to attempt to constrain the parameter based on the methods the parametric method would replace.