# A precise definition of what it means to be an instance of an abstract type

**URL:** <https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [March 16, 2021, 7:45am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270 "2021-03-16T07:45:56Z")\
**Posts on this page:** 20\
**Page:** 1

<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, 7:45am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/1 "2021-03-16T07:45:56Z")

</div>

This question builds on [What is difference between Type{T} and T - #16 by Henrique\_Becker](https://discourse.julialang.org/t/what-is-difference-between-type-t-and-t/19325/16)

Are there any objections to the definition below?

Based on the following two quotes from [Types · The Julia Language](https://docs.julialang.org/en/v1/manual/types/)

> One particularly distinctive feature of Julia’s type system is that concrete types may not subtype each other: all concrete types are final and may only have abstract types as their supertypes.

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

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

Note that, according to this definition, `Type` is an instance of itself because

```Julia
julia> typeof(Type)
UnionAll

julia> UnionAll <: Type
true

```

Moreover, this definition works with examples like `Type{Float64}`. It is an instance of `Type` because `typeof(Type{Float64}) = DataType` and `DataType <: Type` both hold.  
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` provides a potential counterexample because, 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

```

and

```Julia
julia> isa(Ptr{Float64},Ptr)
false

```

Personally, I like definition at the top of this post as I can imagine applying it in the field. There are two ways to rescue it:

1. say that `Ptr` is not an abstract type. Is this reasonable? If so, then is it concrete, or can parametric types be neither abstract, nor concrete?
2. say that `Ptr{Int64}` is not an instance of `Ptr`. This would fit the observation that `Ptr` has no subtypes, but not the observation that `Ptr{Int64} <: Ptr` holds. (I am putting this latter contradiction in a separate topic.)

---

<div class="post-metadata">

**Author:** ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)\
**Post date:** [March 16, 2021, 8:25am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/2 "2021-03-16T08:25:03Z")

</div>

I don’t understand this part of the definition:

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

What is “the value” of an abstract 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 16, 2021, 8:33am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/3 "2021-03-16T08:33:39Z")

</div>

For instance, the value of `Int64` is simply `Int64`, but the concrete type of `Int64` is `typeof(Int64) = DataType`.

---

<div class="post-metadata">

**Author:** ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)\
**Post date:** [March 16, 2021, 8:40am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/4 "2021-03-16T08:40:26Z")

</div>

But why do you need v\_y then? Simply use y in its place.

---

<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:** [March 16, 2021, 9:54am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/5 "2021-03-16T09:54:24Z")

</div>

I’m not sure what you mean by “value vy of y” in your definition. If it’s saying that `y` is an abstract type that implements vy in the way that `Int64` is a concrete type that implements `1`, then that’s impossible because by definition, only concrete types implement. It looks fine if that detail is omitted: in more familiar terms, `x isa y` if and only if `typeof(x) <: y`.

Couple things:

- `isconcretetype(aType)` can be used to distinguish a concrete type and an abstract type. `Ptr` is definitely abstract.
- `Ptr{Float64}` is a subtype, not an instance, of `Ptr`.

---

<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, 9:56am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/6 "2021-03-16T09:56:58Z")

</div>

Well, it depends on what you’re trying to do. When you write an object as a pair you can then consider the concrete type tag of y as its second dimension. Objects and values are then isomorphic.

---

<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, 10:08am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/7 "2021-03-16T10:08:00Z")

</div>

> [@Benny](#):
>
> `Ptr{Float64}` is not an instance, of `Ptr` .

Well, if you are right, then the manual is wrong as it explicitly says that `Ptr{Float64}` is an instance of `Ptr`. But, personally, I agree with you on this point.

But regarding

> [@Benny](#):
>
> `Ptr{Float64}` is a subtype,

consider

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

julia> subtypes(Ptr)
Type[]

```

As you can see, `Ptr` is not in there. Yes, I know it is according to `<:`, but as I point out in [another discourse](https://discourse.julialang.org/t/counterexamples-to-the-interpretation-means-is-a-subtype-of/57274/2), it is not at all clear that `<:` means “is a subtype” in the case of `Ptr`.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [March 16, 2021, 10:31am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/8 "2021-03-16T10:31:50Z")

</div>

> [@path-doc](#):
>
> say that `Ptr` is not an abstract type. Is this reasonable? If so, then is it concrete, or can parametric types be neither abstract, nor concrete?

`Ptr` (like all parametric types where some of the parameters aren’t fully specified) isn’t _a_ single type, it’s a [`UnionAll`](https://docs.julialang.org/en/v1/devdocs/types/#UnionAll-types), an infinite-many collection of concrete types. `Ptr{Float64}` is a concrete realisation of `Ptr`.

> [@path-doc](#):
>
> ```julia
> julia> isa(Ptr{Float64},Ptr)
> false
> 
> ```

This doesn’t make sense: `X isa Y` is the relation “X is an _instance_ of type Y”. Perhaps you wanted either of

```julia
julia> Ptr{Float64} <: Ptr
true

julia> Ptr{Float64}() isa Ptr
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, 10:44am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/9 "2021-03-16T10:44:09Z")

</div>

> [@giordano](#):
>
> `Ptr` (like all parametric types where some of the parameters aren’t fully specified) isn’t _a_ single type, it’s a [`UnionAll`](https://docs.julialang.org/en/v1/devdocs/types/#UnionAll-types), an infinite-many collection of concrete types. `Ptr{Float64}` is a concrete realisation of `Ptr` .

Great, then, since `typeof` returns the concrete type of an object, why do we have

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

```

> [@giordano](#):
>
> This doesn’t make sense: `X isa Y` is the relation “X is an _instance_ of type Y”. Perhaps you wanted either of
> 
> ```julia
> julia> Ptr{Float64} <: Ptr
> true
> 
> julia> Ptr{Float64}() isa Ptr
> true
> 
> ```

Well the manual states that `Ptr{Float64}` is an instance of `Ptr`. See the first line of  
[https://docs.julialang.org/en/v1/manual/types/#UnionAll-Types](https://docs.julialang.org/en/v1/manual/types/#UnionAll-Types)

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [March 16, 2021, 10:54am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/10 "2021-03-16T10:54:18Z")

</div>

> [@path-doc](#):
>
> Great, then, since `typeof` returns the concrete type of an object, why do we have
> 
> ```julia
> julia> typeof(Ptr{Float64})
> DataType
> 
> ```

`Ptr{Float64}` _is_ a data type, why do you think it’s wrong?

> [@path-doc](#):
>
> Well the manual states that `Ptr{Float64}` is an instance of `Ptr` . See the first line of  
> [Types · The Julia Language](https://docs.julialang.org/en/v1/manual/types/#UnionAll-Types)

Would “realisation” instead of “instance” be clearer for you? You can only have instances of concrete types

---

<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:** [March 16, 2021, 10:55am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/11 "2021-03-16T10:55:16Z")

</div>

That first bit isn’t that odd. `Ptr{Float64}()` is an instance of the concrete type `Ptr{Float64}`, and `Ptr{Float64}` is an instance of the concrete type `DataType`. Types are objects/instances, too!

In that thread you linked, I think the takeaway is that `<:` means exactly “is a subtype of”, and that the `subtypes` and `supertypes` methods just cannot be comprehensive.

That line in the manual _is_ odd. Right before that line, it states that `Ptr{Float64}` is a subtype of `Ptr` in the `<:` sense.

---

<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, 11:03am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/12 "2021-03-16T11:03:16Z")

</div>

Okay, so you are saying that realisation \neq instance, right?

Can you please give me a formal definition of _realisation_? I have given you one of _instance_. I like my definition. But my definition does not extend to abstract parametric types precisely because

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

julia> typeof(Ptr{Float64}) <: Ptr
false

```

And everyone here seems to be convinced that `Ptr{Float64}` is a subtype of `Ptr`.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [March 16, 2021, 11:08am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/13 "2021-03-16T11:08:48Z")

</div>

> [@path-doc](#):
>
> Okay, so you are saying that realisation \neq instance, right?

I’m saying that `Ptr` is a family, a set of concrete types. `Ptr{Float64}` is a concrete type of this family/set. Call it “realisation” or whatever you want, I don’t know whether there is a formal name for it. “Instance” here is probably used in a loose way.

---

<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:** [March 16, 2021, 11:12am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/14 "2021-03-16T11:12:57Z")

</div>

I think we should just call it a concrete subtype, just to stick with formal terms.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [March 16, 2021, 11:16am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/15 "2021-03-16T11:16:25Z")

</div>

There is this nice talk by Jeff about the type system:

[![](https://global.discourse-cdn.com/julialang/original/3X/4/9/492c9aff3d96076d5a907e1e76178ed47a4e7de8.jpeg "JuliaCon 2017 | The State of the Type System | Jeff Bezanson") ](https://www.youtube.com/watch?v=Z2LtJUe1q8c)

It’s from 2017 and some details may have changed since then, but I think the most interesting takeaway message is that you should think of types as the set of values they can take, and `<:` is the subset relationship.

---

<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:** [March 16, 2021, 11:28am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/16 "2021-03-16T11:28:23Z")

</div>

If your definition puts any importance on the relation `typeof(Something{Parameter}) <: Something`, I think it’s best you discard it. Maybe it seemed to make sense at first because of `Type`, `UnionAll`, and `DataType`, but those are really more of an exception.

Say you have an object `x` then recursively go through the concrete types by repeatedly running `x = typeof(x)`, eventually you start to cycle through `DataType` because the type system had to begin _somewhere_ to make instances. Note that this is not about the type hierarchy; `Any` was decided to be the union of all types and thus the ultimate supertype, but even `Any` is an instance of `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 16, 2021, 11:37am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/17 "2021-03-16T11:37:58Z")

</div>

> [@Benny](#):
>
> Say you have an object `x` then recursively go through the concrete types by repeatedly running `x = typeof(x)` , eventually you start to cycle through `DataType` because the type system had to begin _somewhere_ to make instances. Note that this is not about the type hierarchy; `Any` was decided to be the union of all types and thus the ultimate supertype, but even `Any` is an instance of `DataType` .

That is the concrete type tree. It is the foundation on which the abstract graph of types is built. Abstract types form the hierarchy, but instances live on the concrete tree. That is the essence of my definition.

---

<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, 11:46am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/18 "2021-03-16T11:46:41Z")

</div>

> [@Benny](#):
>
> If your definition puts any importance on the relation `typeof(Something{Parameter}) <: Something` , I think it’s best you discard it. Maybe it seemed to make sense at first because of `Type` , `UnionAll` , and `DataType` , but those are really more of an exception.

Well not if `Something{Parameter}` is not an abstract type. My definition only applies to abstract types. So is `Ptr` an abstract or concrete supertype of those concrete types `Ptr{x}?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [March 16, 2021, 11:53am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/19 "2021-03-16T11:53:02Z")

</div>

> [@path-doc](#):
>
> So is `Ptr` an abstract or concrete supertype of those concrete types `Ptr{x}?

Again, it’s none of them: it’s a collection, a family, a set of concrete types

---

<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, 11:58am UTC](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270/20 "2021-03-16T11:58:10Z")

</div>

Thanks, so my definition remains intact. (Btw, someone else somewhere was saying that `Ptr` is definitely abstract.) So according to you, parametric supertypes are neither concrete, nor abstract. Though their subtypes are all concrete? I will try to digest.

[Next page](https://discourse.julialang.org/t/a-precise-definition-of-what-it-means-to-be-an-instance-of-an-abstract-type/57270.md?page=2)
