# Unexpected : isstructtype( Vector{Float64}) =\> true

**URL:** <https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283>\
**Category:** General Usage\
**Created:** [April 10, 2022, 12:24am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283 "2022-04-10T00:24:41Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![reumle](https://avatars.discourse-cdn.com/v4/letter/r/5daacb/32.png) [@reumle](https://discourse.julialang.org/u/reumle)\
**Post date:** [April 10, 2022, 12:24am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/1 "2022-04-10T00:24:41Z")

</div>

According to the help, it should not happen…

```julia
isstructtype(T) -> Bool
Determine whether type T was declared as a struct type (i.e. using the struct or mutable struct keyword).

```

1. Is this a bug? Or am I misunderstanding something ?
2. What is the proper way to detect if a variable (more precisely its type) is a `struct` ? In a way that does not also catches simple vectors…

Thanks!

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [April 10, 2022, 12:35am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/2 "2022-04-10T00:35:53Z")

</div>

What do you need this information for? (XY problem?

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [April 10, 2022, 12:49am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/3 "2022-04-10T00:49:53Z")

</div>

Looks like a bug to me, either in the documentation or implementation. If that function is supposed to return `true` there, the documentation doesn’t say that.

The implementation is

```julia
function isstructtype(@nospecialize(t::Type))
    @_pure_meta
    t = unwrap_unionall(t)
    # TODO: what to do for `Union`?
    isa(t, DataType) || return false
    hasfield = !isdefined(t, :types) || !isempty(t.types)
    return hasfield || (t.size == 0 && !isabstracttype(t))
end

```

and `isdefined(Vector{Int}, :types)` returns `true`.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [April 10, 2022, 4:58am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/4 "2022-04-10T04:58:45Z")

</div>

I seem to remember reading in the docs not to use `isstructtype` because a lot of things are struct types in Julia which don’t intuitively seem structy.

---

<div class="post-metadata">

**Author:** ![torrance](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torrance/32/38990_2.png) [@torrance](https://discourse.julialang.org/u/torrance)\
**Post date:** [April 10, 2022, 5:55am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/5 "2022-04-10T05:55:01Z")

</div>

`isstructtype` differentiates a type from being a primitive type or abstract type. It is not about differentiating types from arrays.

An array in Julia is a struct type because it is a struct containing a length, a capacity and memory buffer.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [April 10, 2022, 8:32am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/6 "2022-04-10T08:32:32Z")

</div>

> [@reumle](#):
>
> 1. Is this a bug? Or am I misunderstanding something ?
> 2. What is the proper way to detect if a variable (more precisely its type) is a `struct` ? In a way that does not also catches simple vectors…

1. For bootstrapping reasons arrays, including vectors, are implemented in C but are semantically structs. See [https://github.com/JuliaLang/julia/blob/3d87815b71f7e1a520a50fcc71b50e7b1c155933/base/boot.jl#L3](https://github.com/JuliaLang/julia/blob/3d87815b71f7e1a520a50fcc71b50e7b1c155933/base/boot.jl#L3) and [https://github.com/JuliaLang/julia/blob/3d87815b71f7e1a520a50fcc71b50e7b1c155933/base/boot.jl#L55](https://github.com/JuliaLang/julia/blob/3d87815b71f7e1a520a50fcc71b50e7b1c155933/base/boot.jl#L55).

2. Maybe

```julia
mystructtest(x::AbstractArray) = false
mystructtest(x) = isstructtype(typeof(x))

```

but it really depends on what you need it for.

---

<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:** [April 10, 2022, 8:36am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/7 "2022-04-10T08:36:07Z")

</div>

> [@GunnarFarneback](#):
>
> For bootstrapping reasons arrays, including vectors, are implemented in C but are semantically structs.

Note that even if they’d be implemented in pure julia, they’d still be structs - one hypothetical version could look like

```julia
struct NativeArray{T,N}
   length::Int
   data::Ptr{T}
end

```

(you wouldn’t use this of course, since the data is no longer stored inline and for other reasons).

Containers generally can’t be anything other than structs - having them as primitive types is usually not an option, due to their variable size & different meanings of parts of their bits (i.e. fields).

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [April 10, 2022, 10:13am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/8 "2022-04-10T10:13:05Z")

</div>

Can someone propose a change for the docs so that it’s more accurate?

---

<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:** [April 11, 2022, 5:24am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/9 "2022-04-11T05:24:33Z")

</div>

What about its docs is inaccurate?

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [April 11, 2022, 5:35am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/10 "2022-04-11T05:35:08Z")

</div>

It says that `Vector{Float64}` is `using the struct or mutable struct keyword`, but it isn’t.

---

<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:** [April 11, 2022, 6:27am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/11 "2022-04-11T06:27:00Z")

</div>

That sounds more like a technicality than useful documentation… E.g. if it were to say something like

> Determine whether objects of type T behave no different from structs (i.e. objects declared using the `struct` or `mutable struct` keywords).

I’d bet people would be confused about what other kinds of objects aside from structs & primitive types there are, as that would seemingly imply a third option when there isn’t.

Arrays and vectors are, for all intents and purposes, structs and should be treated as such. How that is checked internally is not relevant and can’t be reduced to how it was written in code anyway - you can always create structs & objects manually using the C API of the runtime when e.g. embedding julia.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [April 11, 2022, 6:34am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/12 "2022-04-11T06:34:14Z")

</div>

The argument could be made that `isprimitive` would have been a more self-explanatory function.

---

<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:** [April 11, 2022, 6:41am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/13 "2022-04-11T06:41:25Z")

</div>

That wouldn’t cover `abstract type` though. You need all three, `isprimitivetype`, `isabstracttype` and `isstructtype` (and we do have all three).

Abstract types are not values at all and don’t have anything associated with them save for their sub/supertype relationships.

Primitive types are values of “plain bits” and no seperate interpretation (=fields) of a part of them, i.e. they are not composite.

[Struct types are values composed of one or more values of some type](https://docs.julialang.org/en/v1/manual/types/#Composite-Types) (primitive or again struct type), i.e. the bits encompassing all of their value have a seperate interpretation apart from being part of the wrapper (they have fields).

Arrays only fit the last definition, as they contain a length & its data (and some other bits) in their (unexposed) fields. How else would you check for whether something is a struct type except for checking whether it has fields? That’s the distinguishing feature after all.

---

<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:** [April 11, 2022, 11:06am UTC](https://discourse.julialang.org/t/unexpected-isstructtype-vector-float64-true/79283/14 "2022-04-11T11:06:23Z")

</div>

> [@Sukera](#):
>
> How else would you check for whether something is a struct type except for checking whether it has fields?

`!isprimitivetype(T) && !isabstracttype(T)` ?
