Inconsistency in comprehension syntax

Consider:

for k in 0:8 println(k) end # works
println([k for k in 0:8])   # works

for k in 0:8, j in 0:k println(binomial(k,j)) end # works
println([binomial(k, j) for k in 0:8, j in 0:k])  # !works

The last line gives: UndefVarError: k not defined.
Why?

Try

julia> println([binomial(k, j) for k in 0:8, j in 0:8 if jā‰¤k])
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 1, 3, 6, 10, 15, 21, 28, 1, 4, 10, 20, 35, 56, 1, 5, 15, 35, 70, 1, 6, 21, 56, 1, 7, 28, 1, 8, 1]
1 Like

Writing [binomial(k, j) for k in 0:8, j in 0:k] only describes what happens in the lower triangular portion of the array. Comprehensions define rectangular arrays ā€” what should happen in the upper triangular part?

Another option: explicitly state what you want to have in the upper triangular part:

julia> [j > k ? 0 : binomial(k, j) for k in 0:8, j in 0:8]
9Ɨ9 Array{Int64,2}:
 1  0   0   0   0   0   0  0  0
 1  1   0   0   0   0   0  0  0
 1  2   1   0   0   0   0  0  0
 1  3   3   1   0   0   0  0  0
 1  4   6   4   1   0   0  0  0
 1  5  10  10   5   1   0  0  0
 1  6  15  20  15   6   1  0  0
 1  7  21  35  35  21   7  1  0
 1  8  28  56  70  56  28  8  1
1 Like

Another expression that works is

[binomial(k, j) for k in 0:8 for j in 0:k]

(replacing the comma with another for) but it yields a 1-d array since the iteration space is no longer a product space.

3 Likes