# Array comprehension is inconsistent, given the column-major property of julia

**URL:** <https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946>\
**Category:** Internals & Design\
**Tags:** question, array\
**Created:** [January 8, 2026, 4:29am UTC](https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946 "2026-01-08T04:29:45Z")\
**Posts on this page:** 9\
**Page:** 2

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [January 11, 2026, 5:39pm UTC](https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946/21 "2026-01-11T17:39:35Z")

</div>

So here’s an annoying bit, `if` applies a filter to the elements, and it removes the multiple dimensions from the multidimensional syntax:

```julia-auto
julia> [(r, c) for r in 1:2, c in 1:3]
2×3 Matrix{Tuple{Int64, Int64}}:
 (1, 1) (1, 2) (1, 3)
 (2, 1) (2, 2) (2, 3)

julia> [(r, c) for r in 1:2, c in 1:3 if iseven(c+r)]
3-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (2, 2)
 (1, 3)

```

We just get a vector of the allowed elements. However, this is not falling back to the nested `for` behavior, which would reverse the axes’ order:

```julia-auto
julia> [(r, c) for r in 1:2 for c in 1:3 if iseven(c+r)]
3-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (1, 3)
 (2, 2)

```

I only use the latter because looking more like the nested for-loop helps, and it never made sense to me to filter a multidimensional syntax and sacrifice the multidimensionality.

We are also unable to filter an axis on its own:

```julia-auto
julia> [(r, c) for r in 1:2 if r > 1, c in 1:3]
ERROR: ParseError:
# Error @ REPL[57]:1:30
[(r, c) for r in 1:2 if r > 1, c in 1:3]
# └ ── Expected `]`

```

A filter depending on 2 axes like `for i=1:4; j=1:3 if i>j for k=5:6` would go a step further than that.

In my experience, `if` works in the nested `for` syntax as expected from the corresponding loop, but you should check your examples in the REPL.

> [@abraemer](#):
>
> Personally, I think it would have been a better choice to use `;` instead `,` in the comprehension

If we’re going that far (in a breaking change), I’d rather not write `for` at all. `for` just makes me think `for`-loop, and I reasonably expect that’s true for most people. Multidimensional array comprehension is an outlier, and taking a cue from 1-dimensional set/list comprehension syntax was going to be weird.

> [@abraemer](#):
>
> The comprehension with comma is a completely different iteration construct conceptually

Interesting that you phrase it as iteration because I can’t find a clear specification. The comprehension docs don’t really say how it’s iterated, but the implementation of a generator iterates a composite `Iterators.product` that changes the leftmost iterators first (column-major order iteration does not imply storage), and both linear indexing and the optional `IndexLinear` trait specify column-major order iteration for `AbstractArray`. `eachindex` seems to leave iteration order open, but I don’t know of an array type that diverges from column-major order, nor do I know what happens if we mix it with typical objects e.g. would `RowMajorIterationArray{Tuple{Int,Int}}(undef, 2, 3) .= ((r, c) for r in 1:2, c in 1:3)` result in an array equal to a `Array` comprehension?

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [January 11, 2026, 8:01pm UTC](https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946/22 "2026-01-11T20:01:00Z")

</div>

> [@Benny](#):
>
> So here’s an annoying bit, `if` applies a filter to the elements, and it removes the multiple dimensions from the multidimensional syntax:

Wow, I didn’t even know that this is possible and also it doesn’t make a lot of sense to me. This seems so obscure to me, I wonder whether this ever was used by someone or whether one could just disallow this behavior and noone would complain…

> [@Benny](#):
>
> Interesting that you phrase it as iteration because I can’t find a clear specification.

I don’t know whether this is an ‘official’ term. I just wanted to refer to symtax constructs that do/mean something loop/iterator/iteration related. Maybe there exists some more precise term.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [January 12, 2026, 6:07am UTC](https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946/23 "2026-01-12T06:07:36Z")

</div>

> [@abraemer](#):
>
> I wonder whether this ever was used by someone

see line 237 below

> <https://github.com/jump-dev/JuMP.jl/blob/9d1dc331f0ec90929b8bd759c03e1c0cd58847a0/docs/src/tutorials/getting_started/getting_started_with_sets_and_indexing.jl#L225-L239>

@odow want to revise?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [January 12, 2026, 7:44am UTC](https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946/24 "2026-01-12T07:44:29Z")

</div>

Why? Seems like it works okay to me

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [January 12, 2026, 7:55am UTC](https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946/25 "2026-01-12T07:55:33Z")

</div>

Interesting. In this case the order of the elements does not matter. So in this specific case it does not matter at all which form of the iteration is used. So the comma saves 3 whole characters 😅

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [January 12, 2026, 8:10am UTC](https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946/26 "2026-01-12T08:10:34Z")

</div>

The order (1 → 2 → 3 → 4) reads awkward, if you imagine the ordinary programming counterpart.

 ![image](https://global.discourse-cdn.com/julialang/original/3X/e/4/e43dcdc9854b40977e11965be2da58fd3782a619.png)

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 12, 2026, 9:03am UTC](https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946/27 "2026-01-12T09:03:32Z")

</div>

> [@abraemer](#):
>
> > [@Benny](#):
> >
> > So here’s an annoying bit, `if` applies a filter to the elements, and it removes the multiple dimensions from the multidimensional syntax:
> 
> Wow, I didn’t even know that this is possible and also it doesn’t make a lot of sense to me. This seems so obscure to me, I wonder whether this ever was used by someone or whether one could just disallow this behavior and noone would complain…

Using a filter (through the `if` clause) would necessarily have to collapse the multidimensional structure. Otherwise, what shape would the output have?

It’s the same as if you do:

```julia-auto
julia> filter(iseven∘sum, [(r, c) for r in 1:2, c in 1:3])
3-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (2, 2)
 (1, 3)

```

or

```julia-auto
julia> filter(>(0.95), rand(4,3,2,5))
3-element Vector{Float64}:
 0.9696942632241587
 0.9939223654034923
 0.9533802058515822

```

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [January 18, 2026, 2:44am UTC](https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946/28 "2026-01-18T02:44:47Z")

</div>

No. For establishing a JuMP Affine Expression, the **iterated for** syntax in comprehension fits better (e.g. to the `JuMP.Containers.SparseAxisArray`).

See this toy example, where the `isum` is reasonable (and I’m making use of it currently in my realistic JuMP code), whereas the `csum` has other meanings.

```julia-auto
julia> csum(t) = sum((println("Info> t=$t, s=$s"); t) for t=t, s=t);

julia> isum(t) = sum((println("Info> t=$t, s=$s"); t) for t=t for s=t);

julia> csum((1, 2, 3))
Info> t=1, s=1
Info> t=2, s=1
Info> t=3, s=1
Info> t=1, s=2
Info> t=2, s=2
Info> t=3, s=2
Info> t=1, s=3
Info> t=2, s=3
Info> t=3, s=3
18

julia> isum((1, 2, 3))
Info> t=1, s=1
Info> t=2, s=2
Info> t=3, s=3
6

```

Other julia users can also take a look, the `csum` here seems to be a completely different construct from the ordinary Cartesian-`for` loop grammar, which can be very confusing to reason about. Cf.

```julia-auto
julia> function c(t)
           for t=t, s=t
               println("Info> t=$t, s=$s")
           end
       end;

julia> c((1,2,3))
Info> t=1, s=1
Info> t=2, s=2
Info> t=3, s=3

```

---

<div class="post-metadata">

**Author:** ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)\
**Post date:** [January 18, 2026, 9:16am UTC](https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946/29 "2026-01-18T09:16:34Z")

</div>

> [@WalterMadelim](#):
>
> ```julia-auto
> julia> csum(t) = sum((println("Info> t=$t, s=$s"); t) for t=t, s=t);
> 
> julia> isum(t) = sum((println("Info> t=$t, s=$s"); t) for t=t for s=t);
> 
> ```

Using `t` for both the collection and the elements within is bound to lead to trouble. If you would write

```julia
csum2(t) = sum(x for x=t, y=t);
isum2(t) = sum(x for x=t for y=x);

```

the difference is immediately obvious. This `csum2` produces the same results (though in a different order) as

```julia
csum3(t) = sum(x for x=t for y=t);

```

`isum2` does not need the second `for` (looping over a singleton) , i.e. it is equivalent to

```julia
isum3(t) = sum(x for x=t); # (or just sum(t) )

```

or

```julia
isum4(t) = sum((y = x; x) for x=t)

```

if for whatever reason you really want a second variable.

* * *

I do agree that it’s annoying that (a summing version of) `c` behaves differently from `csum`. But also here, avoiding `for t=t` takes away the confusion:

```julia
function c_indep(t)
    for x=t, y=t
        println("Info> x=$x, y=$y")
    end
end

function c_dep(t)
    for x=t, y=x
        println("Info> x=$x, y=$y")
    end
end

```

[Previous page](https://discourse.julialang.org/t/array-comprehension-is-inconsistent-given-the-column-major-property-of-julia/134946.md?page=1)
