3 ms·
Why not encode the starting offset into the type domain? Or at least distinguish between normal and unusual. Then the function signature can restrict to 1-offse
by grumpyprole 4y ago
Why not encode the starting offset into the type domain? Or at least distinguish between normal and unusual. Then the function signature can restrict to 1-offset arrays if that is what it assumes internally.
- DNF2 4y agoThat means disallowing indexing with integers, I presume? Since an integer can take the values 0 or 1 equally. And what about the other end of the array. Must every index be restricted by type to be located in the acceptable range?
- markkitti 4y agoIf the function signature said `Array` rather than `AbstractArray`, then this code would have been fine. `Array` indexing starts at `1`. ``` julia> function f(A::Array) println(A[1:length(A)]) end f (generic function with 1 method) julia> f([1,2,3,4]) [1, 2, 3, 4] julia> f(OffsetArray(1:10, -1)) ERROR: MethodError: no method matching f(::OffsetVector{Int64, UnitRange{Int64}}) ``` You could prevent this problem using Julia's type system. The `AbstractArray` might have been too broad. Based on the chronology of the code that might not have been apparent. See other threads for details. Another way would be to treat `firstindex` as a trait and dispatch on that. ``` julia> f(A::AbstractArray) = f(A, Val(firstindex(A))) f (generic function with 1 method) julia> f(A::AbstractArray, firstindex::Val{1}) = println(A[1:length(A)]) f (generic function with 2 methods) julia> f(A::AbstractArray, firstindex::Val{T}) where T = error("Indexing for array does not start at 1") f (generic function with 3 methods) julia> f(A::AbstractArray, firstindex::Val{0}) = println("So you like 0-based indexing?") f (generic function with 4 methods) julia> f([1,2,3,4]) [1, 2, 3, 4] julia> using OffsetArrays julia> f(OffsetArray(1:10, 1)) ERROR: Indexing for array does not start at 1 Stacktrace: [1] error(s::String) @ Base .\error.jl:33 [2] f(A::OffsetVector{Int64, UnitRange{Int64}}, #unused#::Val{2}) @ Main .\REPL[5]:1 [3] f(A::OffsetVector{Int64, UnitRange{Int64}}) @ Main .\REPL[3]:1 [4] top-level scope @ REPL[9]:1 julia> f(OffsetArray(1:10, -1)) So you like 0-based indexing? ```
- DNF2 4y agoThe starting offset is encoded in the type domain, btw, and accessible with the `firstindex` function. But you will still want to calculate indices at runtime, and then out-of-bounds errors will have to be caught at runtime anyway.