Behavior of comprehensions

I have just realized that nested comprehensions have two non-obvious properties.
Consider the following code:

julia> f(i, j) = (println((i,j)); (i,j))                          
f (generic function with 1 method)                                
                                                                  
julia> [f(i, j) for i = 1:2, j = 3:4]                             
(1, 3)                                                            
(2, 3)                                                            
(1, 4)                                                            
(2, 4)                                                            
2×2 Array{Tuple{Int64,Int64},2}:                                  
 (1, 3)  (1, 4)                                                   
 (2, 3)  (2, 4)                                                   
                                                                  
julia> [f(i, j) for i = 1:2 for j = 3:4]                          
(1, 3)                                                            
(1, 4)                                                            
(2, 3)                                                            
(2, 4)                                                            
4-element Array{Tuple{Int64,Int64},1}:                            
 (1, 3)                                                           
 (1, 4)                                                           
 (2, 3)                                                           
 (2, 4)                                                           
                                                                  
julia> [f(i, j) for i = 1:2, j = 3:4 if true]                    
(1, 3)                                                            
(2, 3)                                                            
(1, 4)                                                            
(2, 4)                                                            
4-element Array{Tuple{Int64,Int64},1}:                            
 (1, 3)                                                           
 (2, 3)                                                           
 (1, 4)                                                           
 (2, 4)                                                           

What we can see:

  1. The order of traversal of comprehension with double for loop is different than when using comma loop (as Julia uses column major order);
  2. It is allowed to add condition after comma loop and then we get a vector (not a matrix, as documented) although it is natural to expect to get a vector.

I would document them both, but maybe it is clear from the current documentation and I am missing something.

2 Likes

https://docs.julialang.org/en/latest/manual/arrays/#Comprehensions-1