# Why \[1, 2, 3\] is not a Vector{Number}?

**URL:** <https://discourse.julialang.org/t/why-1-2-3-is-not-a-vector-number/52645>\
**Category:** New to Julia\
**Tags:** question, parametric-types\
**Created:** [December 31, 2020, 8:26am UTC](https://discourse.julialang.org/t/why-1-2-3-is-not-a-vector-number/52645 "2020-12-31T08:26:16Z")\
**Posts on this page:** 1\
**Showing post:** 19

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 3, 2021, 2:02pm UTC](https://discourse.julialang.org/t/why-1-2-3-is-not-a-vector-number/52645/19 "2021-01-03T14:02:36Z")

</div>

> [@greg\_plowman](#):
>
> But Julia doesn’t allow subtyping from concrete types. Presumably there are good reasons for this.

Imagine what this would mean for working with an array `a` of type `Vector{Float64}`, for example:

- Currently, this can be stored as a consecutive sequence of 8-byte chunks in memory, and if the compiler sees `a[i] + 1.5` it knows that it can compile this into a load instruction and a floating-point addition.

- If `Float64` could be sub-typed, however, then the elements of `a` could be any subtypes of `Float64` — they would have to be pointers to “boxes” containing a type tag (to say what type they really are) along with the actual data, and for an expression like `a[i]+1.5` the compiler would need to generate code that chases the pointer, looks at the type tag, and does dynamic (runtime) dispatch to the correct `+` operation.

Moreover, dynamic dispatch in a multiple-dispatch language like Julia is even more expensive than dynamic dispatch in a single-dispatch (traditional OOP) language like C++ (where they have vtables), so **devirtualization** (figuring what what methods to call at compile-time) is a critical optimization, to the point where nearly all optimized Julia code is devirtualized in practice. Making concrete types final (non-subtypable) gives the compiler many more chances for devirtualization. Even in C++, [people often recommend `final` classes](https://devblogs.microsoft.com/cppblog/the-performance-benefits-of-final-classes/) to enable devirtualization.

Because multiple dispatch allows you to add new functions to existing types (see also [this discussion](https://discourse.julialang.org/t/is-julias-way-of-oop-superior-to-c-python-why-julia-doesnt-use-class-based-oop/52058/24) and [this talk](https://www.youtube.com/watch?v=kc9HwsxE1OY) on the [expression problem](https://en.wikipedia.org/wiki/Expression_problem) of OOP), there is much less need for subtyping of concrete types in Julia than there is in OOP languages. Because of that, it was a practical choice to make all concrete types “final”, reaping vast benefits in performance as well as simplifying the language.

---

_[View the full topic](https://discourse.julialang.org/t/why-1-2-3-is-not-a-vector-number/52645)._
