TL;DR I think the type system should take care of converting between
different types of arrays and thus free the user to code against the type
of array they want (OneTo, ZeroTo, Offset, etc).

Maybe I have a deep mis-understanding of how the new generalized offset
arrays are suppose to work in Julia. If so I'd be happy to be set straight.
If not then I think the present system will lead to unnecessary complexity
and bug-ridden code. In the present system one can define array types that
are not one-based but can have arbitrary offsets. This is a great idea but
to make it work a very general system for indexing relative to the ends of
the array has been devised. If one writes a function that accepts an
`AbstractArray` then one MUST use this more general system or produce bugs
when e.g. a `ZeroToArray` is passed in. This puts a large burden on writers
of library code that works on arrays and I think is an unnecessary
complexity.

Since Fortran arrays are a nice example let look at the situation in
Fortran. If I define an array in a function `real arr(-10:10)` then I would
index it using indices that range from -10 to 10. If I pass this into
another function that declared the array using its total size (usually
passed in separately or in a parameter statement) `real arr(21)` then in
that subroutine one would index the array using "normal" indices that range
from 1 to 21. I.E., you state in the function how you want to treat the
array and are not forced to work with in offset form unless you want to. In
my opinion, this is what makes using offset arrays in Fortran sane and is
the key thing that Julia should try to emulate.

One way to get this behavior in Julia would be to use the type system and
`convert`. Since `AbstractArray` has meant until 0.5 a `OneTo` array I
think it is wise that it remain that way so that all old code will work
unchanged (even with the new array types). Thus, I propose adding a new
top-level type above AbstractArray type to capture all arrays something
like:

```
Array{T,N} <: DenseArray{T,N} <: AbstractArray{T,N} <:
AbstractAllArray{T,N} <: Any
```

And the offset arrays would be subtypes of `AbstractAllArrays` on a
different branch

```
OffsetArray{T,N} <: AbstractOffsetArray{T,N} <: AbstractAllArray{T,N} <: Any
```

And similarly for `ZeroToArray`.

Then, if one declares an Array as

```
function func(arr::AbstractArray)
```

one can safely assume it is a 1-based Array inside `func`. If an offset
array is passed into `func` then it is automatically converted to a `OneTo`
array inside `func`. This is the key point of this proposal and is similar
to the auto-conversion of, e.g., Int to Floats in a function call.
Similarly if one declares an array as a `ZeroToArray` in a function and
passes in an `Array` then it will be converted to a `ZeroToArray` in the
function. Some conversions would need more information and thus would be
disallowed (e.g., `Array` to `OffsetArray`). I think this system would go a
long way towards making `ZeroToArray`s and `OffsetArray`s simple to use in
Julia w/o using the generalized indexing techniques introduced in Julia
0.5. Note that it would still be possible to use the `AbstractAllArray`
type and accept all arrays w/o conversion and use the generalized indexing
techniques.

I'm curious what people think about this.

Bob

ps Paste into github to see in formatted form. I'm not sure how to get that
in an email.

Reply via email to