# Why isn't this legal syntax for defining a subtype?

**URL:** <https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479>\
**Category:** New to Julia\
**Tags:** struct\
**Created:** [October 19, 2024, 10:35am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479 "2024-10-19T10:35:05Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [October 19, 2024, 10:35am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/1 "2024-10-19T10:35:05Z")

</div>

I have some abstract type parameterised by a `T` type like this

```julia
abstract type SomeAbstractType{T} end

```

and I want to create a subtype from it and this syntax works

```julia
mutable struct Some{T<:Number} <: SomeAbstractType{T}
    somefield::T
end

```

So in the above, are the two `T`s referring to the something?

I would have thought that the below work

```julia
mutable struct Some{T} <: SomeAbstractType{T} where {T <: Number}
    somefield::T
end

```

but it doesn’t work and gives `ERROR: invalid subtyping in definition of Some: can only subtype data types`.

I don’t really understand what’s going on here. What’s the theoretical reason why the 2nd one doesn’t work?

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [October 19, 2024, 11:12am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/2 "2024-10-19T11:12:49Z")

</div>

I think you can put the `T <: Number` inside one of the other `{T}`, I can’t remember which one.

And remove the `where {...` statement altogether.

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [October 19, 2024, 11:16am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/3 "2024-10-19T11:16:17Z")

</div>

> [@kapple](#):
>
> I can’t remember which one.

yeah. that seems to be some kind of complexity. You mean the example I showed that worked?

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [October 19, 2024, 11:17am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/4 "2024-10-19T11:17:40Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [October 19, 2024, 11:43am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/5 "2024-10-19T11:43:50Z")

</div>

> [@kapple](#):
>
> 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.

i am just confused why it isn’t valid.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [October 19, 2024, 12:49pm UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/6 "2024-10-19T12:49:29Z")

</div>

It does not seem to be valid Julia syntax to add the `where` clause to the `struct` definition.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [October 19, 2024, 2:46pm UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/7 "2024-10-19T14:46:34Z")

</div>

This works

```julia
abstract type SomeAbstractType{T} end

mutable struct Some{T} <: SomeAbstractType{T where {T <: Number}}
      somefield::T
end

```

The question is: is this what you intended?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [October 19, 2024, 4:14pm UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/8 "2024-10-19T16:14:07Z")

</div>

My understanding is a bit limited, but it used to be that both function and struct definitions used similar syntax for type parameters:

```julia
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.

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [October 19, 2024, 9:35pm UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/9 "2024-10-19T21:35:05Z")

</div>

Yeah

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [October 20, 2024, 6:22am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/10 "2024-10-20T06:22:18Z")

</div>

> [@PetrKryslUCSD](#):
>
> The question is: is this what you intended?

…to which the answer is almost certainly: No, because that makes every `Some`, including, e.g. `Some{String}` a subtype of `SomeAbstractType{Number}`.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [October 20, 2024, 6:24am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/11 "2024-10-20T06:24:34Z")

</div>

> [@xiaodai](#):
>
> What’s the theoretical reason why the 2nd one doesn’t work?

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
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.

> [@PetrKryslUCSD](#):
>
> `SomeAbstractType{T where {T <: Number}}`

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
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 

```

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [October 20, 2024, 2:06pm UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/12 "2024-10-20T14:06:13Z")

</div>

Perhaps then what was meant was:

```julia

julia> abstract type SomeAbstractType{T} end
julia> struct A
       a::Int
       end
julia> mutable struct Some{T2<:Number} <: SomeAbstractType{A}
                  somefield::T2
              end

```

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [November 1, 2024, 2:02am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/13 "2024-11-01T02:02:49Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [November 1, 2024, 8:16am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/14 "2024-11-01T08:16:30Z")

</div>

> [@kapple](#):
>
> The docstring of `where` says it’s an iteration to produce a `Union`.

Shouldn’t this have been a new topic?

Anyway, “iterated union” refers to `UnionAll`, not to `Union`. Making a PR. EDIT: here it is:

> <https://github.com/JuliaLang/julia/pull/56411>

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [November 1, 2024, 8:19am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/15 "2024-11-01T08:19:23Z")

</div>

Thanks for the PR.

> [@nsajko](#):
>
> Shouldn’t this have been a new topic?

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?

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [November 1, 2024, 9:38am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/16 "2024-11-01T09:38:47Z")

</div>

> [@kapple](#):
>
> 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.

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [November 1, 2024, 9:43am UTC](https://discourse.julialang.org/t/why-isnt-this-legal-syntax-for-defining-a-subtype/121479/17 "2024-11-01T09:43:14Z")

</div>

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.
