# How to capture a for loop index after break?

**URL:** https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342
**Category:** General Usage
**Created:** [September 9, 2020, 6:56pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342 "2020-09-09T18:56:10Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)
#### Post date: [September 9, 2020, 6:56pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/1 "2020-09-09T18:56:10Z")

</div>

Is there a way to have a non-local scope loop index, so code similar to this:

```julia
for i = 1:9
  if i > 3
    break
  end
end

println(i)

```

works and I don’t have to write:

```julia
j = 0

for i = 1:9
  if i > 3
    j = i
    break
  end
end

println(j)

```

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [September 9, 2020, 7:18pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/2 "2020-09-09T19:18:23Z")

</div>

no easy / canonical way because `for...end` forms a local scope, there’s this hack:

```julia
julia> j = Ref(-1)
Base.RefValue{Int64}(-1)

julia> for j[] = 1:10
           if j[]>3
               break
           end
       end

julia> j[]
4

```

But I’d recommend against it.

---

<div class="post-metadata">

### Author: ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)
#### Post date: [September 9, 2020, 7:25pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/3 "2020-09-09T19:25:40Z")

</div>

Was `for global i = 1:9` syntax ever proposed?

---

<div class="post-metadata">

### Author: ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)
#### Post date: [September 9, 2020, 7:27pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/4 "2020-09-09T19:27:53Z")

</div>

Are you looking for the `outer` keyword?

```julia
function foo(p)
   local i
   for outer i = 1:100
       rand() > p && break
   end
   return i
end

```

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [September 9, 2020, 7:30pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/5 "2020-09-09T19:30:33Z")

</div>

😮 , first time seeing this anywhere and `?outer` has nothing to offer, neither do `for`’s manual page or docs. Btw you don’t need the first `local` I think.

---

<div class="post-metadata">

### Author: ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)
#### Post date: [September 9, 2020, 7:31pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/6 "2020-09-09T19:31:41Z")

</div>

Same here. Really hard to find.

---

<div class="post-metadata">

### Author: ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)
#### Post date: [September 9, 2020, 7:32pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/7 "2020-09-09T19:32:20Z")

</div>

It does seem hard to find. The documentation mentions this feature here:  
[https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Loops-and-Comprehensions](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Loops-and-Comprehensions)

---

<div class="post-metadata">

### Author: ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)
#### Post date: [September 9, 2020, 7:34pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/8 "2020-09-09T19:34:05Z")

</div>

> [@jling](#):
>
> Btw you don’t need the first `local`

True. This works fine:

```julia
function foo(p)
   i = 0
   for outer i = 1:100
       rand() > p && break
   end
   return i
end

```

---

<div class="post-metadata">

### Author: ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)
#### Post date: [September 9, 2020, 7:42pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/9 "2020-09-09T19:42:40Z")

</div>

> [@jling](#):
>
> Btw you don’t need the first `local` I think.

You just need the variable to exist in the outer scope. Using `local` is the least constraining way of doing that.

For example if you decide later to change the type of the loop variable (e.g. to `for i = 1.0 : 10.0`), having `i=0` hardcoded will lead to a type instability. With local, `i` will always have the right type.

Another advantage is that you can reliably check whether the loop ran at all:

```julia
julia> function testfun(p)
           local i
           for i = 1:100
               rand() > p && break
           end
           if @isdefined(i)
               return i
           else
               return 999
           end
       end
testfun (generic function with 1 method)

julia> testfun(0.99)
999

```

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [September 9, 2020, 7:50pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/10 "2020-09-09T19:50:41Z")

</div>

In this case it would be easier to just return I from the loop?

---

<div class="post-metadata">

### Author: ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)
#### Post date: [September 9, 2020, 8:09pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/11 "2020-09-09T20:09:55Z")

</div>

> [@baggepinnen](#):
>
> return I from the loop

You mean return `i`, right? My actual use case is more complex and I can’t do it, but in the `foo` example above, it is definitely an option.

---

<div class="post-metadata">

### Author: ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)
#### Post date: [September 9, 2020, 8:42pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/12 "2020-09-09T20:42:27Z")

</div>

> [@jebej](#):
>
> you can reliably check whether the loop ran at all

In this case I would rather write:

```julia
function testfun(p)
  i = 999
  for outer i = 1:100
    rand() > p && break
  end
  return i
end

```

but I see where `local` may be useful.

---

<div class="post-metadata">

### Author: ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)
#### Post date: [September 10, 2020, 2:05pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/13 "2020-09-10T14:05:52Z")

</div>

BTW, `outer` is not recognized as a keyword by Discourse.

---

<div class="post-metadata">

### Author: ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)
#### Post date: [September 10, 2020, 4:12pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/14 "2020-09-10T16:12:18Z")

</div>

That’s because it’s not actually a reserved keyword, `outer` only has special meaning in the iteration specification of for loops and generators. That’s why the following are still completely valid syntax:

```julia
julia> outer = 7
7

julia> for outer in 1:3
           println(outer)
       end
1
2
3

julia> for outer * inner ∈ 1:3
           println(1 * 2)
       end
1
2
3

```

---

<div class="post-metadata">

### Author: ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)
#### Post date: [September 10, 2020, 4:19pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/15 "2020-09-10T16:19:04Z")

</div>

Hmm, that looks quite a bit error-prone.

---

<div class="post-metadata">

### Author: ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)
#### Post date: [September 10, 2020, 5:51pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/16 "2020-09-10T17:51:57Z")

</div>

Why is that error prone? It would be pretty annoying not being able to name variables `outer` in normal code anymore, just for this special for loop syntax.

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [September 10, 2020, 6:07pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/17 "2020-09-10T18:07:28Z")

</div>

(I had no idea what `for outer * inner ∈ 1:3` does and I had to stare at `Meta.@lower` output for a while. This is so diabolical and I love this example 🤣)

---

<div class="post-metadata">

### Author: ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)
#### Post date: [September 10, 2020, 7:13pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/18 "2020-09-10T19:13:18Z")

</div>

> [@simeonschaub](#):
>
> Why is that error prone

OK, maybe not error-prone, since compiler will help here, but context sensitive behavior of `outer` may be a bit confusing. I don’t think identifiers, which may or may not be restricted keywords depending on context, are widely used in programming languages. Maybe I’m too old date…

---

<div class="post-metadata">

### Author: ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)
#### Post date: [September 10, 2020, 7:21pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/19 "2020-09-10T19:21:29Z")

</div>

> [@tkf](#):
>
> This is so diabolical

Way too diabolical for me! Can you explain what is happening there? Why are we getting anything other than `2` as in:

```julia
julia> println(1 * 2)
2

```

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [September 10, 2020, 8:53pm UTC](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342/20 "2020-09-10T20:53:00Z")

</div>

I don’t want spoil anyone’s fun so I’m hiding the explanation behind `[spoiler]` (click to remove the blur):

```julia
for outer * inner ∈ 1:3
    println(1 * 2)
end

```

behaves as above since it is equivalent to

```julia
for x ∈ 1:3
    _ * _ = x
    println(:this_is_ignored * :this_is_also_ignored)
end

```

(Note also that `_ * _ = x` is equivalent to `*(_, _) = x`; i.e., it defines a closure named `*`.)

Perhaps the best way to see what is going on is to print what `*` is:

```julia
julia> for outer * inner ∈ 1:3
           @show *
           println(:ignored * :ignored)
       end
* = var"#*#12"{Int64}(1)
1
* = var"#*#12"{Int64}(2)
2
* = var"#*#12"{Int64}(3)
3

```

[Next page](https://discourse.julialang.org/t/how-to-capture-a-for-loop-index-after-break/46342.md?page=2)
