# Possible bug: return inside an array comprehension

**URL:** <https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193>\
**Category:** General Usage\
**Tags:** bug\
**Created:** [June 10, 2017, 2:47am UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193 "2017-06-10T02:47:31Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [June 10, 2017, 2:47am UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193/1 "2017-06-10T02:47:31Z")

</div>

I wonder if the behaviour below is the intended behaviour for `return` inside an array comprehension. It seems to me that f1 and f2 should behave in the same way, terminating the function as soon as `return` is reached once. This syntax might be useful when using short-circuit if statements inside an array comprehension, returning something different for each condition, where the conditions follow an indexable pattern, that can be looped over.

```julia
julia> f1() = [return 1 for i in 1:5]
f1 (generic function with 1 method)

julia> f1()
5-element Array{Int64,1}:
 1
 1
 1
 1
 1
 
julia> function f2()
           for i in 1:5
               return 1
           end
       end
f2 (generic function with 1 method)

julia> f2()
1

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [June 10, 2017, 3:05am UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193/2 "2017-06-10T03:05:34Z")

</div>

The current behavior is expected. If it is confusing, we can make it an error.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [June 10, 2017, 3:08am UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193/3 "2017-06-10T03:08:14Z")

</div>

I mean it is kind of confusing especially that `[return 1 for i in 1:5]` and `return [1 for i in 1:5]` behave the same way, so I don’t see a useful way in which this behaviour could be used. But the more intuitive behaviour would be the one resembled by f2. Changing its behaviour is not an option?

Edited to add: I guess making it an error at least guards against misinterpretation, so if nothing more can happen before v0.6, then it is still better the current situation.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [June 10, 2017, 3:21am UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193/4 "2017-06-10T03:21:34Z")

</div>

> [@mohamed82008](#):
>
> Changing its behaviour is not an option?

No. Comprehension is a wrapper around generator and the body is used to generate a closure. `return` in there never does what you want it to and cannot be implemented that way. Making it an error is certainly possible and will be consistent with 0.4.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [June 10, 2017, 3:29am UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193/5 "2017-06-10T03:29:57Z")

</div>

I just thought it was worth mentioning. The same syntax works as expected with throw() instead of return which I believe is not really a surprise or a problem.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 10, 2017, 6:58am UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193/6 "2017-06-10T06:58:46Z")

</div>

Please don’t make it an error unless there is a compelling reason, conceptual equivalence to a closure is useful and should be retained, as it makes reasoning about comprehensions more transparent. Eg a macro could use `return` in the body, etc.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [June 10, 2017, 11:47am UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193/7 "2017-06-10T11:47:42Z")

</div>

It doesn’t make sense to me either that the return should be completely ignored, and I don’t think disallowing return in this case really changes any reasoning about the comprehension.  
It seems like with a `return 1`, it should return a 1, not `[1,1,1,1,1]`, if you have a `throw` it doesn’t try to ignore the `throw` and continue execution either. Since returning a single value would be type unstable and not useful, it seems best to have the compiler give an error in this case.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 10, 2017, 11:50am UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193/8 "2017-06-10T11:50:37Z")

</div>

> [@ScottPJones](#):
>
> It doesn’t make sense to me either that the return should be completely ignored

It is not ignored. It is called from the (implicit) closure, which returns.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [June 10, 2017, 12:01pm UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193/9 "2017-06-10T12:01:54Z")

</div>

OK, I understand your point now, but I haven’t found anything in the documentation about comprehensions or generators that discusses that conceptual equivalence to a closure. Maybe you could make a PR and add that to the docs, so that the rationale behind this behavior is clear? (even if it is still surprising to see)  
Maybe this is also something that `Lint.jl` could warn about, since the return here is not useful at all, just confusing.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 10, 2017, 1:10pm UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193/10 "2017-06-10T13:10:43Z")

</div>

I don’t know if it is meant to stay this way or just the current implementation. AFAICT the closures should not affect anything else (eg scoping), just the effect of a `return`.

---

<div class="post-metadata">

**Author:** ![joshbode](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshbode/32/260_2.png) [@joshbode](https://discourse.julialang.org/u/joshbode)\
**Post date:** [June 10, 2017, 11:28pm UTC](https://discourse.julialang.org/t/possible-bug-return-inside-an-array-comprehension/4193/11 "2017-06-10T23:28:45Z")

</div>

`return` can show up in other potentially unclear (and unusual) situations, too.

### `module`:

```julia
0.6.0-rc3.0> module X
               a = 1
               b = 2
               return
               c = 3
             end

0.6.0-rc3.0> X.c
3

```

which looks like it doesn’t do anything.

### `let`:

```julia
0.6.0-rc3.0> let x = 1
               return
               println("Yo!")
             end

```

doesn’t print anything, but probably makes sense though.

### `type`:

```julia
0.6.0-rc3.0> type Foo
               x::Int
               return
               y::Int
             end

0.6.0-rc3.0> Foo(1, 2)
ERROR: MethodError: no method matching Foo(::Int64, ::Int64)

```
