A for loop where the counter isn't used

question

#1

I sometimes need to repeat some code n times, but I don’t care what iteration I’m on. In those cases I do this:

for _ in 1:n 
    ...
end

Is there anything out there better than that? I’m merely curious if I’ve missed some construct/function that better suits this use-case.
Thanks!


#2

Not sure if it’s worth it but here is a macro :wink:

macro loop(n, ex)
    return quote
        for _ ∈ 1:$n
            $ex
        end
    end
end

@loop 3 println("hello")

@loop 10 begin
    println("yep")
end

#3

I don’t know if it is intentional or documented, but the empty tuple () seems to work as a “non-variable”. For example, for () in 1:n will work, and make it clear that you will not use the iteration index.

(Similarly, ((), x) = foo()` can be a way of expressing that you only care about the second element of a returned tuple.)


#4

The underscore _ is probably a good choice, as it’s actually meant to be used in Julia as a “don’t care” variable. In fact, as of Julia 1.0 it’s illegal to read from _ (you can only assign to it), so the compiler is free to ignore anything you assign to it, opening up additional optimization possibilities.

julia> _, x = (1, 2)
(1, 2)

julia> x
2

julia> y = _
ERROR: syntax: all-underscore identifier used as rvalue

#5

The compiler doesnt need this help. It only helps the reader.


#6

See also the discussion at


#7

I think just using _ is the best solution. It nicely covers a special case, and works fine in other contexts (closures) if you restructure your code.


#8

From a readability and performance point of view, for _ = 1:N is the way to go. However, Julia is not short of alternatives. Here are some:

julia> for _=1:3 println("loop") end
loop
loop
loop

julia> foreach(_->println("loop"),1:3)
loop
loop
loop

julia> map(_->println("loop"),1:3);
loop
loop
loop

julia> (1:3).|>_->println("loop");
loop
loop
loop

julia> (_->println("loop")).(1:3);
loop
loop
loop

julia> [println("loop") for _=1:3];
loop
loop
loop

julia> eval.(fill(:(println("loop")),3));
loop
loop
loop

julia> eval(Meta.parse("println(\"loop\");"^3))
loop
loop
loop

#9

Note that strictly speaking, only the first one is a loop (so that it can be used to eg accumulate a local state).

Also, the last two ones are kind of icky, too; evaling code parsed from plain text is not something one would do in practice.