# Vector with negative indices extending getindex

**URL:** <https://discourse.julialang.org/t/vector-with-negative-indices-extending-getindex/104286>\
**Category:** General Usage\
**Tags:** question, base, methods\
**Created:** [September 26, 2023, 9:50pm UTC](https://discourse.julialang.org/t/vector-with-negative-indices-extending-getindex/104286 "2023-09-26T21:50:55Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gvdr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gvdr/32/6387_2.png) [@gvdr](https://discourse.julialang.org/u/gvdr)\
**Post date:** [September 26, 2023, 9:50pm UTC](https://discourse.julialang.org/t/vector-with-negative-indices-extending-getindex/104286/1 "2023-09-26T21:50:55Z")

</div>

Hello. I’m trying to extend the method(s) for get index so to have the ability of accessing a numeric vector, `Vector{T} where T<:Number`, at a negative (or zero) index and get `zero(T)`.

The intended behaviour is something like:

```julia
julia> v = [1,2,3,4];

julia> v[1]
1

julia> v[-2]
0

```

I considered using a combination of `PaddedViews` and `OffsetArrays`, but that would be cumbersome, as I don’t know a priori the maximum value of the negative indices I might use.

Hence, the solution seems to be extending the `Base.getindex()` (not necessarily `setindex!()` as I don’t intend to assign any value in those indices).

I **naively** tried with (don’t try the following, as it crashes julia)

```julia
import Base: getindex
getindex(v::V,i::Int) where Vector{T} where T<:Number = i > 0 ? Base.getindex(v,i) : zero(T)

```

This causes a stack overflow error and crashes Julia. I believe I understand why (it is causing an infinite recursion, as it is overwriting the method ALSO for positive `i`).

How would you fix this? Can I distinguish _by type_ between positive and negative (or zero) values of `i`? Is there some other obvious way of obtaining the same behaviour that I don’t see?

PS I’m trying to avoid to define new types (but that might be the error in my approach).

---

<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:** [September 26, 2023, 10:09pm UTC](https://discourse.julialang.org/t/vector-with-negative-indices-extending-getindex/104286/2 "2023-09-26T22:09:28Z")

</div>

Yeah, that’s not possible. You’ve either got to define a new type or use a different function. I’d do the latter:

```julia
get(A, i) = i <= 0 ? zero(eltype(A)) : A[i]

```

Custom array types in Julia don’t demand much, but they do demand that you know their size.

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [September 26, 2023, 10:59pm UTC](https://discourse.julialang.org/t/vector-with-negative-indices-extending-getindex/104286/3 "2023-09-26T22:59:45Z")

</div>

In fact, the suggested function already exists in Base (in some capacity)

```julia
julia> A = 11:15
11:15

julia> get(A,1,0) # returns A[1]
11

julia> get(A,-3,zero(eltype(A))) # A[-3] is not defined so returns `zero(eltype(A))`
0

```

`get` is generally used to access a particular index/key from a collection or to return the default if the index/key is not present. But you’ll have to write your own (as in the above suggestion) if you still want it to error for too-big indices.

By the way, your initial attempt to overload `Base.getindex` is an example of [type piracy](https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy) and is very dangerous for the reasons you discovered. It changes how the function works everywhere, which is a recipe for chaos. Even if it didn’t produce an error, it might break functionality in more subtle ways (which is even worse because it may be hard to notice).

But if you need this to apply to `getindex` or its syntax (i.e., `A[i]`), specifically, and can’t simply use a different access function (like `get` or your own version), then you’ll need to define a new type of array to do it safely. Making simple types is usually fairly easy. In this case, you may want to reference and follow the [array interface](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array).

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [September 26, 2023, 11:07pm UTC](https://discourse.julialang.org/t/vector-with-negative-indices-extending-getindex/104286/4 "2023-09-26T23:07:06Z")

</div>

A good way might be to leverage an existing implementation (sometimes it is hard to find, but often exists for useful stuff):

```julia
julia> using ImageFiltering

julia> v = [1,2,3,4];

julia> vv = BorderArray(v, Fill(0, (50,)));

julia> vv[1]
1

julia> vv[-2]
0

julia> size(vv)
(104,)

```

This implementation comes from the mature Images eco-system. The size, as you can see, includes the padding, but it doesn’t take up memory.

---

<div class="post-metadata">

**Author:** ![gvdr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gvdr/32/6387_2.png) [@gvdr](https://discourse.julialang.org/u/gvdr)\
**Post date:** [September 27, 2023, 12:19am UTC](https://discourse.julialang.org/t/vector-with-negative-indices-extending-getindex/104286/5 "2023-09-27T00:19:00Z")

</div>

This requires to know in advance the desired length of the padding (and does change the length of the passed view).

But I will take a look at how they implement it.
