"i in 3" is valid and continues to cost me some debug time :(

Hi,

I spent a few hours to fix a bug where I was using an integer in place of a range

for i in N
    do_something_with_i(i)
end

instead of

for i in 1:N
    do_something_with_i(i)
end

I wish i in 3 wasn’t a valid expression, but it is…
Maybe some iDE hint could save me some time ? VSCode extension , other ?

VS Code should already warn you in that case:

It’s obviously quite basic, but at least addresses the literal case. Shouldn’t be too hard to support the case mentioned here too, probably.

2 Likes

I do not get any warning for this function:

function toto(N::Int)
    for i ∈ N
        println("i=$i")
    end
end

Maybe, I forgot to activate specific options in vscode ?
Edit : You already said that it only catches the litteral case. Thanks.
The non litteral case would be useful :slight_smile:

Yeah, this only works for literal values in the loop iterator. So i in 1 will show the warning, but i in N won’t even if we could know that N is an Int. That case is much harder to do reliably, although your case should be ok.

3 Likes

This is why my preferred style (which I seem to be alone in, but c’est la vie) is to always use for i = 1:n when the inferrable is a literal range object and always use for x in itr when the intervals is anything besides a literal range. This uses the syntactic choice between = and in as an extra bit communicating user intent. If you accidentally write for i = n you could get a warning that you should either change it to for i = 1:n if you wanted to iterate a range or for i in n if you wanted to iterate n as a collection.

9 Likes

Everything more sophisticated will need to go into JETLS :slight_smile:

6 Likes

I am afraid I do not get your point :sweat_smile:

function titi(N::Int)
    for i = N
        println("i=$i")
    end
end

does not trigger any warning. And in the for i = case I cannot even wish that the in operator was undefined for scalar RHS.

Super Cool !

Will these hints be in the next release ?

I think Stefan’s point was

(emphasis added)

2 Likes

Naturally :slight_smile:

1 Like

Yes, it would be a linter warning, but I haven’t convinced anyone. But it’s simple enough to check for that you can even do it with a regex.

2 Likes

If you would like to have a warning, you could do this:

function Base.iterate(x::Integer)
    @warn "Iterating over an integer (value: $x) - did you mean to use a range like 1:$x?"
    # Actually, integers iterate once, yielding themselves
    return (x, nothing)
end

function Base.iterate(x::Integer, state)
    @warn "Iterating over an integer (value: $x) - did you mean to use a range like 1:$x?"
    return nothing  # Original behavior: iterate once
end

So that is the orgiginal implementation of iterators for numbers and now it just throws a warning. That has the benefit over error that it doesnt break packages which use them.

3 Likes

Neat.
“gentle” kind if type piracy ?

This breaks parts of the REPL in Julia 1.12.3:

  1. Input randn(5) (or sin(5) , or sin(5) without the trailing space), don’t press Enter yet.
  2. On the same line input .. The result should be randn(5) .
  3. The warning will appear.
julia> randn(5) .┌ Warning: Iterating over an integer (value: 1) - did you mean to use a range like 1:1?
└ @ Main REPL[1]:2
┌ Warning: Iterating over an integer (value: 1) - did you mean to use a range like 1:1?
└ @ Main REPL[2]:2
julia> sin(5) .┌ Warning: Iterating over an integer (value: 1) - did you mean to use a range like 1:1?
└ @ Main REPL[1]:2
┌ Warning: Iterating over an integer (value: 1) - did you mean to use a range like 1:1?
└ @ Main REPL[2]:2

That does not seem to be the case for me, with the same julia version:

Ahh I get what you mean.
Something like this randn(5).? But what is the . supposed to do?

I meant “input sin(5) . in the same line”, see edit to my post.

I tried to trigger some weird behavior with matrix multiplication, but everything worked fine. Then I tried elementwise multiplication and wanted to input randn(5) .* randn(5), but got the warnings in the middle of writing randn(5) ..

Ahh I get what you mean.

Well I guess that is to be expected when you do this kind of type piracy :laughing:

You will get the warnings everywhere, also in other packages. Even the REPL I guess :pirate_flag: :parrot: