-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Explicit concrete type constraint in UnionAll #30363
Comments
This type appears to be a subset of the intersection of julia> T3 = Tuple{T,T,Ref{>:T}} where T
Tuple{T,T,Ref{#s1} where #s1>:T} where T
julia> T3 <: T1
true
julia> T3 <: T2
true That seems correct: if
Therefore, we know that Note, however, that I'm not sure if this alleviates the need for this feature or not. It does, however, seem that |
Hm, yes, that seems correct. Amazing. Makes me wonder whether there is a case where intersection actually does need this feature. |
I really like this. If we permit concreteness bounds, then this could be used to get internally rid of the diagonal rule, and simplify everything, right? I.e. the diagonal If we are at it, I'd like to also multiply the type-lattice with I'm not sure about syntax; retiring the diagonal syntax for e.g. |
Not having thought it through, here are two possible ideas:
Syntax that would not require introducing any new identifiers or keywords or parsing support: at the cost of possibly giving the impression that arbitrary predicates can take the role of |
We allow
UnionAll
s to constrain the bound type variable to concrete types, but only implicitly by the diagonal rule. E.g. inTuple{T,T} where T
,T
can only be a concrete type. Sometimes, it would be helpful if this constraint could be enabled explicitly. Two examples from the top of my head:typeof(x)
ifx
could not be inferred exactly. Say,x
is only inferred asNumber
, thentypeof(x)
is inferred asType{T} where T<:Number
. Obviously,T
here could be constrained to a concrete type, ifUnionAll
allowed that. (I vaguely remember an issue where inference consideringf(::Type{Union{}})
forf(typeof(x))
came as a bit of a surprise.)There presently is no way to express the intersection (which would be
Tuple{T,T,Ref{T}} where T
withT
concrete). (Expert question: would this and #29368 suffice to make our type system closed under intersection?)Notably, it seems much less useful the other way round, i.e. to allow a typevar to take an abstract type, even if it falls under the diagonal rule. Nevertheless, I'd imagine this to be implemented by an extra
Bool
field inTypeVar
orUnionAll
, indicating whether abstract types are allowed.We probably also would want to provide some syntax (in addition to directly calling the
TypeVar
orUnionAll
constructor). However, if we choose the default behavior of thewhere
clause to match the current diagonal rule, I'm not sure how often that would actually be needed in user code. So we might get away with a construct likefoo(x::Ref{T}) where !abstract T
.The text was updated successfully, but these errors were encountered: