UndefVarError with list comprehensions, but not with for...end

It would be nice to be able to do the following without the UndefVarError:

julia> reduce(+, 1 for i in 1:2, j in i:3; init = 0)
ERROR: UndefVarError: i not defined
Stacktrace:
 [1] top-level scope at none:1

julia> sum(1 for i in 1:2, j in i:3)
ERROR: UndefVarError: i not defined
Stacktrace:
 [1] top-level scope at none:1

I understand you can workaround it using if statements:

julia> sum(1 for i in 1:2, j in 1:3 if j>=i)
5

but it would be nice to not have to do it this way…

Having iterators depend on other iterators works with standard for loops:

julia> for i in 1:2, j in i:3
       1
       end

It would also be great if you could create sparse arrays using similar notation:

julia> [1 for i in 1:2, j in i:3]
ERROR: UndefVarError: i not defined
Stacktrace:
 [1] top-level scope at none:1

I believe you need to replace the comma by another for and then it should work:

julia> sum(1 for i in 1:2 for j in i:3)
5

That’s an even better workaround. Would be nice to not have the extra for in there though…
Thanks @dpsanders

The , makes a matrix in the context of a comprehension / generator. But you don’t have a matrix when j depends on i.

2 Likes

they do different things:

julia> [x+y for x in 1:2, y in 2:3]
2×2 Matrix{Int64}:
 3  4
 4  5

julia> [x+y for x in 1:2 for y in 2:3]
4-element Vector{Int64}:
 3
 4
 4
 5
4 Likes

That makes sense. It would be nice if it made a sparse matrix when needed so that you could use it in a more straightforward fashion in sum or reduce as is done when creating variable arrays in JuMP:

julia> @variable(model, x[i=1:2, j=i:2])
JuMP.Containers.SparseAxisArray{VariableRef,2,Tuple{Int64,Int64}} with 3 entries:
  [1, 2]  =  x[1,2]
  [2, 2]  =  x[2,2]
  [1, 1]  =  x[1,1]

But then, I guess you could just have a custom sum within JuMP to do sums over these variables…