-
-
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
Defining alternate parametric orderings #36213
Comments
An alternative solution to this problem would be to put restrictions on the parametric types to avoid creating invalid type definitions and keep using a constructor to perform the parameter re-arranging. Such a solution could look like the following: struct Bound{name} end
const Open = Bound{:open}
const Closed = Bound{:closed}
const Unbounded = Bound{:unbounded}
isbound(name::Symbol) = name in (:open, :closed, :unbounded)
struct Interval{T,L<:Bound,R<:Bound}
left::T
right::T
end
function Interval{L, R}(left::T, right::T) where {T,L,R}
isbound(L) || error("Unsupported left-bound provided: $L")
isbound(R) || error("Unsupported right-bound provided: $R")
Interval{T,Bound{L},Bound{R}}(left, right)
end However, since the type restrictions need to always be valid we are unable to call the custom constructor even though that constructor doesn't apply any restrictions: julia> Interval{:open,:closed}(1,2)
ERROR: TypeError: in Type, in L, expected L<:Bound, got Symbol
Stacktrace:
[1] top-level scope at REPL[9]:1 I can open a separate issue if this seems like a valid idea |
For constructors, your example only possible because you are stealing another type parameter. If you put a bound on the type parameter in the struct definition, this will not work: julia> struct Interval{T<:Real,L,R}
left::T
right::T
end
julia> Interval{L, R}(left::T, right::T) where {T,L,R} = Interval{T,L,R}(left, right)
julia> Interval{T}(left, right) where T = Interval{T,:closed,:closed}(convert(T, left), convert(T, right))
julia> Interval{:open, :closed}(1, 2)
ERROR: TypeError: in Interval, in T, expected T<:Real, got a value of type Symbol
Stacktrace:
[1] top-level scope at REPL[6]:1 |
I mentioned this in the comment above. Possibly the type parameter restrictions should only be applied when calling |
Ah you did, sorry. I don't know if the compiler is currently using this information, but I do know that removing that restriction would not let the compiler assume some bound on the type parameter for the purpose of optimizing or inferring the code inside the method. |
I've encountered a scenario where it would be very convenient to define an alternate definition of a parametric type when only a subset of the parameters are defined. An example of what I would like to have would probably be written as:
Where
L
andR
are symbols defining if the left/right side of the interval are:open
or:closed
. Having such a definition would allow me to have a convenient way to write types such as:It should be noted that it is currently possible to define constructors that re-arrange the parameters in this way:
which works as expected:
But defining constructors such as these can be confusing if a user attempts to define a similar type in the same way:
The text was updated successfully, but these errors were encountered: