# Why isn't \`size\` always inferred to be an Integer?

**URL:** https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139
**Category:** General Usage
**Tags:** inference, compilation
**Created:** [January 24, 2022, 4:09pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139 "2022-01-24T16:09:16Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [January 24, 2022, 4:09pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/1 "2022-01-24T16:09:16Z")

</div>

I have also spent an endless number of hours in `SnooptCompile` to achieve improvements of 1-2 seconds in compile time. One thing that I really can’t understand is why taking the `size` or `length` of a var that is `Any` returns an `Any`.  
Damn it, `size` can only be an Int.

```julia
@code_warntype GMT.common_plot_xyz("", [0.0 0.0; 1.0 1.0], "", true, false)
...
152 ─ %813 = GMT.length(val::AbstractArray)::Any
│ %814 = GMT.size(arg1@_125, 1)::Any
│ %815 = (%813 != %814)::Any

```

---

<div class="post-metadata">

### Author: ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)
#### Post date: [January 24, 2022, 4:28pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/2 "2022-01-24T16:28:39Z")

</div>

```julia
julia> struct Bad <: AbstractVector{Int} end

julia> Base.size(::Bad, args...) = missing

```

Where is your god now?  
Joking aside, the problem is that the compiler can’t prove that someone didn’t do the equivalent of what I just did above. That’s why it needs to return `Any`.

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [January 24, 2022, 4:36pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/3 "2022-01-24T16:36:03Z")

</div>

I wont go into discussing this as it quickly dives into territories where I cannot go, but it seems a week reason. If it can’t just error. The docs seem clear

```julia
size(A::AbstractArray, [dim])

  Return a tuple containing the dimensions of A.

```

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [January 24, 2022, 5:09pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/4 "2022-01-24T17:09:54Z")

</div>

> [@joa-quim](#):
>
> Damn it, `size` can only be an Int

Not necessarily. Even with only builtin types:

```julia
julia> R = big(1):big(2)^400
1:2582249878086908589655919172003011874329705792829223512830659356540647622016841194629645353280137831435903171972747493376

julia> length(R)
2582249878086908589655919172003011874329705792829223512830659356540647622016841194629645353280137831435903171972747493376

julia> typeof(ans)
BigInt

julia> R isa AbstractArray
true

```

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [January 24, 2022, 5:14pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/5 "2022-01-24T17:14:25Z")

</div>

> [@mbauman](#):
>
> ```julia
> julia> typeof(ans)
> BigInt
> 
> ```

Fine. As long as it’s not a `Any` that keeps propagating. How can we be expected to prevent `Any's` propagation with all this?

And I think I meant an Integer

```julia
julia> BigInt <: Integer
true

```

---

<div class="post-metadata">

### Author: ![suavesito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suavesito/32/34386_2.png) [@suavesito](https://discourse.julialang.org/u/suavesito)
#### Post date: [January 24, 2022, 5:28pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/6 "2022-01-24T17:28:10Z")

</div>

> [@joa-quim](#):
>
> How can we be expected to prevent `Any's` propagation with all this?

Converting it to an `Int`? I mean, if you know that is what it should be, let it be. 😛

Also, a function barrier may work? Don’t know the rest of the code so IDK.

---

<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: [January 24, 2022, 5:33pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/7 "2022-01-24T17:33:34Z")

</div>

> [@joa-quim](#):
>
> The docs seem clear

I don’t think the compiler reads the docs. If it can’t prove it, it has to be `Any`. I mean, how else could it work?

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [January 24, 2022, 5:38pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/8 "2022-01-24T17:38:47Z")

</div>

> [@jakobnissen](#):
>
> ```julia
> julia> struct Bad <: AbstractVector{Int} end
> 
> julia> Base.size(::Bad, args...) = missing
> 
> ```

Never fully Groked the concept but isn’t this type piracy? And if yes, why comply with it?

---

<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: [January 24, 2022, 5:40pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/9 "2022-01-24T17:40:23Z")

</div>

> [@joa-quim](#):
>
> isn’t this type piracy?

No, if `Bad` is your own type, you actually _have to_ make your own `size`.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [January 24, 2022, 5:44pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/10 "2022-01-24T17:44:03Z")

</div>

> [@joa-quim](#):
>
> And I think I meant an Integer

Knowing it’s gotta be an `Integer` is, really, not any better than `Any` for the purposes of the compiler and possible runtime speed. It still needs the costly indirection to figure out what instructions to use, and it can’t just shove it into a 64-bit register.

---

<div class="post-metadata">

### Author: ![suavesito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suavesito/32/34386_2.png) [@suavesito](https://discourse.julialang.org/u/suavesito)
#### Post date: [January 24, 2022, 5:42pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/11 "2022-01-24T17:42:33Z")

</div>

This is not type-piracy. The type `Bad` is defined inside the actual “module” and you define `Base.size` on it.

IIUC type piracy is that you define an external function to your module to a type external to it. Something like this

```julia
module A
function f() end
end

module B
struct MyType end
end

module C
import ..A: f
import ..B: MyType

function f(x::MyType) end # type piracy
end

```

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [January 24, 2022, 5:46pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/12 "2022-01-24T17:46:01Z")

</div>

Thanks, this I can understand.

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [January 24, 2022, 6:46pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/13 "2022-01-24T18:46:16Z")

</div>

And on the same spirit of this thread, how can a `string` return a Any

```julia
└──── goto #157
155 ─ %823 = GMT.string(val)::Any
│ %824 = (%823 != "indata")::Any

```

---

<div class="post-metadata">

### Author: ![suavesito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suavesito/32/34386_2.png) [@suavesito](https://discourse.julialang.org/u/suavesito)
#### Post date: [January 24, 2022, 6:48pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/14 "2022-01-24T18:48:01Z")

</div>

Same, even though we “know” the interfaces, the compiler cannot guaranteed always that they are respected.

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [January 24, 2022, 6:48pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/15 "2022-01-24T18:48:28Z")

</div>

I think you may be taking this output too seriously. Does it actually cause type instability to propagate in your package?

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [January 24, 2022, 6:49pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/16 "2022-01-24T18:49:45Z")

</div>

It’s not literally returning `Any` — the compiler just isn’t sure _what_ it might return at runtime. And it’s because the compiler doesn’t know what type `val` will be, so it doesn’t know what method of `string` will be called.

Just as in the size example, the trouble isn’t so much `string` (or `size`), but upstream of that — sort out the stability of their arguments and they’ll then be stable.

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [January 24, 2022, 6:51pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/17 "2022-01-24T18:51:32Z")

</div>

Maybe not, but what I know is the module in question is precompiled and it still takes a further ~6 seconds to run on the first run. I try to reduce that and the only thing I can tie to the the potential instabilities … and ~zero success.

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [January 24, 2022, 6:53pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/18 "2022-01-24T18:53:59Z")

</div>

As @mbauman says it’s something else in the function thats unstable. You can fix that, or if thats not possible split the function into 2 functions to create a function barrier, so as much of it as possible is stable.

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [January 24, 2022, 6:56pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/19 "2022-01-24T18:56:03Z")

</div>

> [@mbauman](#):
>
> sort out the stability of their arguments and they’ll then be stable.

I know that, but in this case it’s an impossible task because those are derived from input arguments to the function and they can have different types. Nothing really important for run time … as long as per-compilation had worked well. But it didn’t and I’m just trying to find out why and the `Any's` are the beasts to chase, so we are told.

And to give it more context, this the function I’m referring to [https://github.com/GenericMappingTools/GMT.jl/blob/master/src/psxy.jl#L7](https://github.com/GenericMappingTools/GMT.jl/blob/master/src/psxy.jl#L7). The source of the `Any's` is the `kwargs` tht are converted into a `Dict(:symbol, Any)` and from there anything extracted from the `Dict` is a `Any`. Have no idea on how to work around this.  
But again, this does not seem to hurt runtime … after compilation of first run, hence latency.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [January 24, 2022, 6:58pm UTC](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139/20 "2022-01-24T18:58:08Z")

</div>

~~Type instabilities in end-packages tend to impact _runtime_ speed, not the (pre-)compile time.~~ In upstream libraries, yes, they can indeed become one of the magnets for invalidation, but ~~I don’t think they’re typically troublesome at the point where I think you are.~~

This conversation is now circling back to the original thread from which it was split — we can go back to [Taking TTFX seriously: Can we make common packages faster to load and use](https://discourse.julialang.org/t/taking-ttfx-seriously-can-we-make-common-packages-faster-to-load-and-use/74949/) for concrete tips for reducing that compile time.

[Next page](https://discourse.julialang.org/t/why-isnt-size-always-inferred-to-be-an-integer/75139.md?page=2)
