Oh yes. My weak short term memory at demonstration there sorry.
I guess then the question is, what extra information do you expect your non-working example to provide the compiler that isn’t in the working example?
Or are you saying that it’s reasonable that your non-working example should be valid syntax? If so then, I suppose I’d agree in my limited perspective.
My understanding is a bit limited, but it used to be that both function and struct definitions used similar syntax for type parameters:
struct Foo{T<:Number}
...
end
function bar{T<:Number}(x::T)
...
end
The where clause was introduced later (~v0.7?) in order to improve certain things that was difficult to express clearly with the old syntax. Currently, the syntax Foo{SomeType}(x) necessarily means you are looking at a constructor.
So where is a newer syntax, introduced out of a need, but, imo, less aesthetically pleasing than the old syntax.
The curly braces immediately following the struct’s name is the parametric type’s where clause, and it doesn’t make sense to allow another location for a possibly different where clause.
julia> struct Y{N isa Int} end # proof by error message
ERROR: syntax: invalid variable expression in "where" around REPL[64]:1
The 2nd one could be a valid alternative syntax, but Julia decided on the 1st. The 1st obviously saves a bit of typing, but the bigger advantage is the clarity that the clause is limiting the parameters of the defined type, not its declared supertype. This is not like methods’ where clauses limiting all preceding arguments.
This is exactly equal to SomeAbstractType{Number}, the T effectively disappears and is unrelated to the parameter in Some{T}. This is verified to occur in type definitions:
julia> mutable struct X{T} <: Ref{T where {T <: Number}}
somefield::T
end
julia> dump(X)
UnionAll
var: TypeVar
name: Symbol T
lb: Union{}
ub: Any
body: X{T} <: Ref{Number}
somefield::T
julia> abstract type SomeAbstractType{T} end
julia> struct A
a::Int
end
julia> mutable struct Some{T2<:Number} <: SomeAbstractType{A}
somefield::T2
end
The docstring of where says it’s an iteration to produce a Union.
Does this suggest that usage of where in struct definitions doesn’t make sense because it would mean you’re making multiple definitions at once which means they all conflict?
The original question somewhat asks why the where keyword isn’t valid for use in struct definitions. I thought it kind of makes some sense to bring up the docstring to address the original question. Am I wrong?
Technically yes. First, where’s docstring says “iterated union”, not the type Union. The Manual describes UnionAll as iterated unions, hence the PR to clarify this in the docstring. Second, the first optional curly braces in the type definition’s header is the type’s where clause, I showed this earlier in the thread. There’s no implication of making multiple definitions, just one definition of an iterated union of types.
But actually no, this is relevant discussion, at least in my opinion. A bit late, but I don’t think it’s been long enough to firmly justify a new thread either.
Thanks for the clarification, evidently I didn’t fully understand some of the discussion, hence my question and if I was in the right direction (which I wasn’t), some suggestion on why. Thanks again.