4 ms·
Is "for i in 1:length(A)" ever correct? Should Julia just emit a warning any time it encounters that pattern? Or maybe something slightly more complicated, such
by rcthompson 4y ago
Is "for i in 1:length(A)" ever correct? Should Julia just emit a warning any time it encounters that pattern? Or maybe something slightly more complicated, such as that pattern followed by usage of i to index into A inside the loop?
- TimTheTinker 4y ago> Is "for i in 1:length(A)" ever correct? In some rare cases, it very well might be exactly what the code's author intended and needed. I tend to lean towards when Martin Fowler calls an "enabling attitude"[0] (as opposed to a "directing attitude") -- that is, when faced with a choice about how to design the primitives of an interface, I lean more often towards providing flexibility, and I try to avoid choosing ahead of time what users aren't allowed to do. It's better to document what's usually the wrong way to do something than to enforce it in the design. You can never guess what amazing things people will create when they are given flexible, unrestricted primitives. So for cases like this, I think it's better to rely on a flexible linting tool (if available) than warnings or errors. [0] https://martinfowler.com/bliki/SoftwareDevelopmentAttitude.html https://martinfowler.com/bliki/SoftwareDevelopmentAttitude.h...
- dan-robertson 4y agoWhy not have a feature to allow you to turn off the warning? E.g. have something recognise 1:length(x) and complain unless you write e.g. @nowarn eachindex before it.
- kristofferc 4y agoWarning about such things is the job for a linter. There is a linter for Julia so such a thing could be added there. It shouldn't be a runtime warning though, like you propose.
- rashidrafeek 4y agoIt is correct if `A` is of type `Array` as normal Array in julia has 1-based indexing. It is incorrect if `A` is of some other type which subtypes `AbstractArray` as these may not follow 1-based indexing. But this case errors normally due to bounds checking. The OP talks about the case where even bounds checking is turned off using `@inbounds` for speed and thus silently gives wrong answers without giving an error. An issue was created sometime ago in StaticLint.jl to fix this: https://github.com/julia-vscode/StaticLint.jl/issues/337 https://github.com/julia-vscode/StaticLint.jl/issues/337
- cmcaine 4y agoIt's correct if you want to do something `length(A)` times and want an iteration counter, but it's never better than `for idx in eachindex(A)` if what you actually want are indexes into A (which is of course the much more common case). Julia did not initially support arrays that aren't indexed from 1 (experimental support added in Julia 0.5, I don't know when it was finalised), and at that time I'm not even sure we had something like eachindex, certainly there would be no reason why someone would use it for an array.
- a1369209993 4y ago> Is "for i in 1:length(A)" ever correct? Yes, actually. While I have approximately zero knownledge of Julia specifically, a language-independent example might be: B = OneBasedArray(length(A)) A_ = iter(A) for i in 1:length(A) { B[i] = pop(A_) } assert(iter_isdone(A_)) And if that looks contrived... yes; it is contrived. > that pattern followed by usage of i to index into A inside the loop? I can't think of any legitimate uses for that, but there probably are some; make sure to allow: len = length(A) for i in 1:len ... as a `if( (x = foo()) )`-style workaround.