# What is difference between Type{T} and T

**URL:** <https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325>\
**Category:** New to Julia\
**Tags:** type, parametric-types\
**Created:** [January 6, 2019, 3:42pm UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325 "2019-01-06T15:42:15Z")\
**Posts on this page:** 18\
**Page:** 3

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 12, 2021, 9:28am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/41 "2021-03-12T09:28:54Z")

</div>

I am glad that you find the paper helpful.

However, I don’t think that a formal understanding of the edge cases of Julia’s type system is necessary for being productive in Julia. A lot of concepts are very intuitive, and having to think about complex type graphs in Julia code may be a code smell in itself.

---

<div class="post-metadata">

**Author:** ![swissr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/swissr/32/208_2.png) [@swissr](https://discourse.julialang.org/u/swissr)\
**Post date:** [March 12, 2021, 10:54am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/42 "2021-03-12T10:54:46Z")

</div>

> [@goretkin](#):
>
> I can’t find it, but there is a recording of a talk, probably given by Jeff, that shows a 2D grid layout of values, with one dimension showing a subtyping relation and another dimension showing the `typeof` relation. It shows the following self-loops:
> 
> ```julia
> julia> typeof(DataType)
> DataType
> 
> julia> supertype(Any)
> Any
> 
> ```
> 
> If someone can find that talk, I would appreciate a time-link to it and a screenshot of that slide.

That should be the talk [Introduction to Julia Internals](https://www.youtube.com/watch?v=osdeT-tWjzk). I’d recommend to watch it at least three times, screenshot at ~5:50.

 ![objectgraph](https://global.discourse-cdn.com/julialang/original/3X/4/3/43e53113dc2c424c6b96db70b68be0d42790526d.jpeg)

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [March 12, 2021, 1:07pm UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/43 "2021-03-12T13:07:01Z")

</div>

For clarification, the right box of each double-box is the _value_ and the left box is its corresponding _type_.

---

<div class="post-metadata">

**Author:** ![path-doc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/path-doc/32/19183_2.png) [@path-doc](https://discourse.julialang.org/u/path-doc)\
**Post date:** [March 13, 2021, 11:27am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/44 "2021-03-13T11:27:57Z")

</div>

This diagram and talk are very helpful, thanks. I now have an answer to my original short question.

`DataType` is indeed the top of the type tree according to `typeof` (not `isa` or `<:`). It’s nice to see my intuition was correct even though I didn’t have the vocabulary to express this earlier.

Moreover, `DataType` is unique in the sense that it’s the only type that’s equal to its value. That’s the fixed-point property.

That’s great, thanks!

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [March 13, 2021, 11:38am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/45 "2021-03-13T11:38:40Z")

</div>

While technically true, it’s not really useful to think of it that way - type computations are done in regards to `<:`, which has `Any` as its top type and `Union{}` as its bottom type. `typeof` is also not a relation, contrary to `<:`, as it’s 1-ary and not binary.

It’s more accurate to say that each value has some type defined by `typeof`, which can be related to one another via `<:`.

---

<div class="post-metadata">

**Author:** ![path-doc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/path-doc/32/19183_2.png) [@path-doc](https://discourse.julialang.org/u/path-doc)\
**Post date:** [March 13, 2021, 11:43am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/46 "2021-03-13T11:43:30Z")

</div>

It’s not my way of thinking, its a fact: `DataType` is the top according to `typeof`, not according to `<:` of course.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [March 13, 2021, 11:44am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/47 "2021-03-13T11:44:40Z")

</div>

`typeof` does not establish a relation though. There is no (partial) order defined by applying it - you need `<:` to establish that. In some sense, the graphic above is misleading in that regard since it suggests that there is.

I think what you’re thinking about is recursively applying `typeof`, in which case, yes, that chain is what you end up with, but again, that is orthogonal to subtyping and `Type{T}` vs `T`.

---

<div class="post-metadata">

**Author:** ![path-doc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/path-doc/32/19183_2.png) [@path-doc](https://discourse.julialang.org/u/path-doc)\
**Post date:** [March 13, 2021, 11:48am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/48 "2021-03-13T11:48:54Z")

</div>

> [@Sukera](#):
>
> I think what you’re thinking about is recursively applying `typeof` , in which case, yes, that chain is what you end up with, but again, that is orthogonal to subtyping and `Type{T}` vs `T` .

Yes, you or I may not have written one down, but `typeof` will be associated with a binary relation, lets call it `R`. According to `R`, `DataType` is top.

Yes, it is distinct from or independent of `<:`.

Very cool. I love getting to the bottom of things.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [March 13, 2021, 11:58am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/49 "2021-03-13T11:58:15Z")

</div>

Right, that’s what I meant. In graph parlance, that relation can only ever be applied \<=2 times before arriving at the `DataType` loop, so it’s not really a useful relation when trying to work with it. You just loose a lot of information in each application of `typeof`. You can picture it like (type on the left, value on the right again)

- DataType|DataType
  - DataType|Any (abstract types don’t have instances, but Any and Union are special anyway)
  - DataType|Real
  - DataType|Number
  - DataType|Integer
  - DataType|Int (concrete types have all their values as instances)
    - Int|0
    - Int|1
    - …

  - DataType|String
    - String|“hello”
    - …

  - DataType|Union
    - Union|Union{String,Int}
    - …

  - and so on for all types in existence

and as it works now, it will never get to a ~~third~~ fourth sublevel here. It’s a very shallow, very wide tree (that could be considered an implementation detail to allow types to be used as values).

I guess I technically could put `Int|1` under `DataType|Integer` as well, but that’s exactly the point where `<:` comes into play, so that’s why I didnt. You’d also lose the representation of “going up one level is one application of `typeof`”.

---

<div class="post-metadata">

**Author:** ![path-doc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/path-doc/32/19183_2.png) [@path-doc](https://discourse.julialang.org/u/path-doc)\
**Post date:** [March 13, 2021, 12:23pm UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/50 "2021-03-13T12:23:40Z")

</div>

Thanks it’s structure of that left-hand-side that I wanted to understand. I mean, for obvious reason, there is a lot more out there about `<:` because that’s the relation we need when passing bits of data around. But one interpretation of Jeff Bezanson in the 2014 video is that much of the power of Julia lies in understanding both sides of the type coin: the “tag” on the left and the “bits” on the right (or type and value as you put it).

Around 4:26 😜

> We go nuts with it.

---

<div class="post-metadata">

**Author:** ![path-doc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/path-doc/32/19183_2.png) [@path-doc](https://discourse.julialang.org/u/path-doc)\
**Post date:** [March 13, 2021, 1:44pm UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/51 "2021-03-13T13:44:42Z")

</div>

@goretkin Sincere apologies for confusion here. I’m afraid I didn’t have the product structure \text{tags} \times \text{bits} in mind when we were discussing this. ~~I now see that `R` and `<:` are independently defined on \text{tags} and \text{bits} respectively.~~ (Where tags and bits are the terminology of Jeff Bezanson in the 2014 video.)

> [@path-doc](#):
>
> > [@goretkin](#):
> >
> > Note that it’s not the case that all the nodes have that self-loop, rather `DataType` is _unique_ in that way. So it’s not that the relation `R(a, b) = (a == typeof(b))` is reflexive. It is most certainly not.
> 
> Great, so this establishes that `<:` is not a partial order. Further clarification on what you mean by “unique” would be useful:
> 
> ```julia
> julia> DataType <: DataType
> true
> 
> julia> Any <: Any
> true
> 
> julia> Type <: Type
> true
> 
> julia> Int <: Int
> true
> 
> ```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [March 13, 2021, 7:04pm UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/52 "2021-03-13T19:04:52Z")

</div>

I do not know if this was already cited. But on [another recent thread](https://discourse.julialang.org/t/weird-tuple-types-that-seem-like-they-should-be-disallowed/57080/1) the [issue #29368 redesign typeof(::Type)](https://github.com/JuliaLang/julia/issues/29368#) was mentioned, and right on the original post:

> A related issue is that types like `DataType` and `Type{Int}` have an overly-complex subtype and specificity relationship: one is not a subtype of the other, but their intersection is non-empty, _and_ we’re not able to accurately represent that intersection. For various reasons (including backwards compatibility) subtyping currently gets this wrong on purpose, making `Type{Int} <: DataType` true.

---

<div class="post-metadata">

**Author:** ![path-doc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/path-doc/32/19183_2.png) [@path-doc](https://discourse.julialang.org/u/path-doc)\
**Post date:** [March 14, 2021, 7:17am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/53 "2021-03-14T07:17:05Z")

</div>

For future reference and the sake of completeness, I wish to clear up the answer to the second “longer” question that I asked. To more precise, I will clarify the sense in which _concrete types_ form a tree. In particular, I’ll now complete the description of the partial ordering R on the set of objects that is induced by the function `typeof` and show that R describes an inverted tree with \text{DataType} \times \text{DataType} at the top.

**The Concrete Type Tree**  
It is not a completely naive construction. The most basic problem is that (as per appendix A of [Julia subtyping: a rational reconstruction | Proceedings of the ACM on Programming Languages](https://dl.acm.org/doi/10.1145/3276483)) the domain of `typeof` is not only the set of type tags it also accepts values. Thus (contrary to what I suggested in a previous post) we cannot define R on type tags alone.

**The graph of `typeof` and the set of objects X.**  
In what follows, I take as given that the left-hand side of every object is a “concrete type tag”, henceforth a member of the set \text{ctypes}. The right-hand side of every object is the value of the object and a member of the set \text{values}. Note that every t \in \text{ctypes} satisfies t = v for some v \in \text{values}. Every object x is an element of the Cartesian product X = \text{ctypes} \times \text{values}. (Note that X is simply a transposition of the functional graph of \text{typeof}.)

Objects x = t\_x \times v\_x such that v\_x \in \text{values} - \text{ctypes} are, by definition “leaves” of the graph since v\_x does not belong to the image of \text{typeof}. Let L denote the set of such objects. For every object x = t\_x \times v\_x such that v\_x \in \text{ctypes}, there exists an object y = t\_y \times v\_y \in X such that \text{typeof}(v\_y) = v\_x. Let \neg L denote the latter set of objects (chosen because such objects are never leaves). Then L \cup (\neg L) is equal to X.

**The definition of R.**  
We will take R to be a binary relation on X with asymmetric part P and symmetric part I. R is then the disjoint union of P and I and, as a binary relation, it is a subset of the product of X\times X.

**Definition of I.** Take I to be the main diagonal of X \times X, so that it is by definition reflexive. Then R is also anti-symmetric because x \mathbin{I} y implies x = y.

**Definition of P.** Let the binary relation Q be defined by:

- for every x = t\_x \times v\_x and y = t\_y \times v\_y in X, let x \mathbin{Q} y if, and only if, for some sequence of compositions (\text{typeof} \circ \cdots \circ \text{typeof})(v\_x) = v\_y. Note that \text{typeof} never cycles as per the Appendix of [Julia subtyping: a rational reconstruction | Proceedings of the ACM on Programming Languages](https://dl.acm.org/doi/10.1145/3276483).

Now let P = Q - \{y \times y\} where y is the object \text{DataType}\times \text{DataType}. Because of the \text{DataType} is the unique fixed point of \text{typeof}, P is indeed asymmetric.

It remains to be shown that R is transitive. Suppose not. Then there exist x , y , z \in X such that x \mathbin{R} y \mathbin{R} z and \neg (x \mathbin{R} z). Then \neg (x \mathbin{R} z) and symmetry of I implies x \neq z. Moreover x \mathbin{R} y and \neg(x \mathbin{R} z) together imply that y \neq z. Similarly, y \mathbin{R} z and \neg (x \mathbin{R} z) together imply that x \neq y. Thus, x, y and z are pairwise distinct.

Then, together, anti-symmetry of R and x \mathbin{R} y \mathbin{R} z imply that both x \mathbin{P} y and y \mathbin{P} z. This is equivalent to \text{typeof} (v\_x) = v\_y and \text{typeof}(v\_y) = v\_z. But then (\text{typeof} \circ \text{typeof}) (v\_x) = v\_z, so that x \mathbin{P} z. This contradicts the assumption that \neg ( x \mathbin{R} z).

Thus R is indeed a partial order. The fact that R is an inverted tree follows from anti-symmetry of R and the fact that P is formed via repeated composition of \text{typeof}.

**Note 1.** The unique fixed point of the (monotone increasing in the partial order R) map v \mapsto \text{typeof}(v) = t is \text{DataType}.  
**Note 2.** Via the example at the bottom of page 17 of [Julia subtyping: a rational reconstruction | Proceedings of the ACM on Programming Languages](https://dl.acm.org/doi/10.1145/3276483), `<:` is intransitive. Though this is a bug, this implies that the tree (X,R) is in fact the only type tree we have in Julia! (Though I’m not sure how sub/super types deals with the intransitivities of `<:`.)  
_ **Note 3.** _ Any relation that we might induce from `isa` is, via my preceding post, intransitive and hence not a partial order.  
_ **Note 4.** _ The above construction shows that we could also have simply worked with values. This is because the construction of R relies on \text{typeof}: \text{values} \rightarrow \text{values}. In other words, we can define another relation R' on \text{values} that is order isomorphic to R. This supports the statement “values are objects in Julia”. (Though I would probably formalise that statement as “values are isomorphic to objects in Julia”.) So contrary to previous comments, we do not need the product structure to construct R. However, I think it is useful to leave the product structure in as it allows us to make the connection with `<:`. To demonstrate, consider the following quote from the manual ([Types · The Julia Language](https://docs.julialang.org/en/v1/manual/types/)):

> When the type is abstract, it suffices for the value to be implemented by a concrete type that is a subtype of the abstract type.

In the present formalisation, I believe this translates as: for arbitrary object x = t\_x \times v\_x and abstract type y = t\_y \times v\_y, if t\_x \< v\_y, then x is an instance of y. I assume that this can be strengthened to the

**Definition** : Object x is an _instance_ of the abstract type y if, and only if, the concrete type t\_x of x and the value v\_y of y satisfy t\_x \<: v\_y.

Thus, for example, `Any` is an instance of itself since

```Julia
julia> typeof(Any)
DataType

julia> DataType <: Any
true

```

---

<div class="post-metadata">

**Author:** ![path-doc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/path-doc/32/19183_2.png) [@path-doc](https://discourse.julialang.org/u/path-doc)\
**Post date:** [March 16, 2021, 6:42am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/54 "2021-03-16T06:42:18Z")

</div>

Are there any objections to the following?

**Definition** : Object x is an _instance_ of the abstract type y if, and only if, the concrete type t\_x of x and the value v\_y of y satisfy t\_x \<: v\_y.

For instance, `Type` is an instance of itself because

```Julia
julia> typeof(Type)
UnionAll

julia> UnionAll <: Type
true

```

But `UnionAll` is not an instance of itself

```Julia
julia> typeof(UnionAll)
DataType

julia> DataType <: UnionAll
false

```

Indeed, via the same argument, no type in the chain `(Int64, Signed, Integer, Real, Number)` is an instance of itself.

Whilst I am comfortable with the above, the `Ptr` doesn’t seem to fit the bill: according to the manual it has “instances” such as `Ptr{Int64}` and `Ptr{Float64}`, but

```Julia
julia> typeof(Ptr{Float64})
DataType

julia> DataType <: Ptr
false

```

But a closer look at `Ptr` also shows that `<:` is not recoverable from `subtypes`:

```Julia
julia> subtypes(Ptr)
Type[]

julia> Ptr{Float64} <: Ptr
true

```

But this section of the manual is factually incorrect because it also states:

> And of course, all specific pointer types are subtypes of the umbrella [`Ptr`](https://docs.julialang.org/en/v1/base/c/#Core.Ptr) type:

The function `supertypes` also disagrees with `<:` here since

```Julia
julia> supertypes(Ptr{Float64})
(Ptr{Float64}, Ref{Float64}, Any)

julia> supertypes(Ptr)
(Ptr, Ref{T} where T, Any)

```

Personally, I would settle for the definition at the top of this post: it is clear as daylight.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 17, 2021, 8:15am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/55 "2021-03-17T08:15:05Z")

</div>

> [@path-doc](#):
>
> and the value v\_y of y

I don’t understand what that means.

---

<div class="post-metadata">

**Author:** ![path-doc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/path-doc/32/19183_2.png) [@path-doc](https://discourse.julialang.org/u/path-doc)\
**Post date:** [March 17, 2021, 10:07am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/56 "2021-03-17T10:07:46Z")

</div>

For example, x = \text{int64} \times 1 is just a mathematical formalisation of `1::Int64`. Then v\_x= 1 and t\_x = \text{Int64}. (I only put the type tag on the left because that’s how it appears in the image below.)  
[![](https://global.discourse-cdn.com/julialang/original/3X/4/3/43e53113dc2c424c6b96db70b68be0d42790526d.jpeg) ](https://global.discourse-cdn.com/julialang/original/3X/4/3/43e53113dc2c424c6b96db70b68be0d42790526d.jpeg)  
For types, which, as the manual says, are also values, v\_x is just the name of x. For example, the value of `Any` is `Any`, but the concrete type tag of `Any` is `Datatype`. So, in this formalisation, if y is the object `Any`, then y = \text{DataType} \times \text{Any}, so that v\_y = \text{Any} and t\_y = \text{DataType}.

---

<div class="post-metadata">

**Author:** ![path-doc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/path-doc/32/19183_2.png) [@path-doc](https://discourse.julialang.org/u/path-doc)\
**Post date:** [March 17, 2021, 11:34am UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/57 "2021-03-17T11:34:41Z")

</div>

I think the definition is logically sound. But, I am confused about the definition of abstract types. On the one hand the manual (and other sources) say that abstract types cannot be instantiated. On the other, the manual also says of singleton types:

> For each type, T, the “singleton type” Type{T} is an abstract type whose only instance is the object T.

According to my definition, `T` is not an instance of `Type{T}` since

```Julia
julia> typeof(Int64)
DataType

julia> DataType <: Type{Int64}
false

```

For real clarity, I would like to change the definition to say _indirect instance_ instead of _instance_. But then it seems weird to say that `Type` is an indirect instance of itself, which it is since:

```Julia
julia> typeof(Type)
UnionAll

julia> UnionAll <: Type
true

```

I’m now looking for is a precise definition of abstract type in the context of Julia. Is it simply one that has been created via a line like the following?

```Julia
julia> abstract type Foo end

```

Or can “abstract” be a derived property? So, we can deduce that `y` is abstract because it cannot be instantiated?

I would also need a precise definition of _instantiation_. Is it the following object-oriented programming definition?

> an **instance** is a concrete occurrence of any [object](https://en.wikipedia.org/wiki/Object_(computer_science)), existing usually during the [runtime](https://en.wikipedia.org/wiki/Run_time_(program_lifecycle_phase)) of a computer program.

---

<div class="post-metadata">

**Author:** ![path-doc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/path-doc/32/19183_2.png) [@path-doc](https://discourse.julialang.org/u/path-doc)\
**Post date:** [March 17, 2021, 12:18pm UTC](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/58 "2021-03-17T12:18:58Z")

</div>

I think an appropriate definition of abstract is one that is complementary to concrete. For then a type y is concrete if, and only if, there exists an object x such that its concrete type \text{typeof}(x) is equal to y. For example,

```Julia
julia> x = [1.0]
1-element Array{Float64,1}:
 1.0

julia> y = Array{Float64,1}
Array{Float64,1}

julia> typeof(x) == y
true

```

Then, since there is no x such that \text{typeof}(x) = \text{Array}, `Array` is an abstract parametric type. `Ptr` is the same.

So then, in line with the manual, Abstract types (such as singleton types and abstract parametric types) may have instances but not “instantiations”. This almost rescues my definition because instances of abstract types are allowed even though instantiations are not!

> **original definition**
>
> > [@path-doc](#):
> >
> > **Definition** : Object x is an _instance_ of the abstract type y if, and only if, the concrete type t\_x of x and the value v\_y of y satisfy t\_x\<:v\_y.

But, in the end, I think the singleton types example means that I have to weaken the definition slightly

> **singleton type example**
>
> > [@path-doc](#):
> >
> > > For each type, T, the “singleton type” Type{T} is an abstract type whose only instance is the object T.
> > 
> > According to my definition, `T` is not an instance of `Type{T}` since
> > 
> > ```julia
> > julia> typeof(Int64)
> > DataType
> > 
> > julia> DataType <: Type{Int64}
> > false
> > 
> > ```

We arrive at:  
**Definition** : Object x is an _instance_ of the abstract type y if, ~~and only if~~ ,

1. the concrete type t\_x of x and the value v\_y of y satisfy t\_x\<:v\_y, or
2. y is a singleton type and x is its instance (can be verified using `isa`)
3. …

[Previous page](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325.md?page=2)
