# I don't understand reducing over empty iterators

**URL:** <https://discourse.julialang.org/t/i-dont-understand-reducing-over-empty-iterators/133870>\
**Category:** General Usage\
**Created:** [November 14, 2025, 11:42am UTC](https://discourse.julialang.org/t/i-dont-understand-reducing-over-empty-iterators/133870 "2025-11-14T11:42:50Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)\
**Post date:** [November 14, 2025, 11:42am UTC](https://discourse.julialang.org/t/i-dont-understand-reducing-over-empty-iterators/133870/1 "2025-11-14T11:42:50Z")

</div>

Consider the following example where I get this error even though I provide init

```julia-auto
julia> foo(x, y, a_set) = x - sum(y[i] for i in a_set, init = zero(eltype(y)))
foo (generic function with 1 method)

julia> foo(3, ones(4), Set{Int}())
ERROR: ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
Stacktrace:
  [1] _empty_reduce_error()
    @ Base .\reduce.jl:311
  [2] mapreduce_empty(f::Function, op::Base.BottomRF{typeof(Base.add_sum)}, T::Type)
    @ Base .\reduce.jl:313
  [3] reduce_empty(op::Base.MappingRF{var"#foo##0#foo##1"{…}, Base.BottomRF{…}}, ::Type{Tuple{…}})
    @ Base .\reduce.jl:350
  [4] reduce_empty_iter
    @ .\reduce.jl:373 [inlined]
  [5] reduce_empty_iter
    @ .\reduce.jl:372 [inlined]
  [6] foldl_impl
    @ .\reduce.jl:41 [inlined]
  [7] mapfoldl_impl
    @ .\reduce.jl:36 [inlined]
  [8] mapfoldl
    @ .\reduce.jl:167 [inlined]
  [9] mapreduce
    @ .\reduce.jl:299 [inlined]
 [10] sum
    @ .\reduce.jl:524 [inlined]
 [11] sum
    @ .\reduce.jl:553 [inlined]
 [12] foo(x::Int64, y::Vector{Float64}, a_set::Set{Int64})
    @ Main .\REPL[3]:1
 [13] top-level scope
    @ REPL[4]:1
Some type information was truncated. Use `show(err)` to see complete types.

```

I don’t understand why this does not work. It works if I collect the iterator first but the whole point of a generator is to avoid this collection. Is there no way around? I feel like I’m missing something.

---

<div class="post-metadata">

**Author:** ![mxhbl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mxhbl/32/211886_2.png) [@mxhbl](https://discourse.julialang.org/u/mxhbl)\
**Post date:** [November 14, 2025, 11:45am UTC](https://discourse.julialang.org/t/i-dont-understand-reducing-over-empty-iterators/133870/2 "2025-11-14T11:45:45Z")

</div>

You are missing a semicolon in `sum`. Using a comma leads to `init` not being parsed as a keyword argument.

```julia-repl
julia> foo(x, y, a_set) = x - sum(y[i] for i in a_set; init = zero(eltype(y)))
foo (generic function with 1 method)

julia> foo(3, ones(4), Set{Int}())
3.0

```

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [November 14, 2025, 11:49am UTC](https://discourse.julialang.org/t/i-dont-understand-reducing-over-empty-iterators/133870/3 "2025-11-14T11:49:33Z")

</div>

Someone actually just ran into basically the same thing yesterday [on Zulip](https://julialang.zulipchat.com/#narrow/channel/274208-helpdesk-.28published.29/topic/sum.20with.20wrong.20keyword.20argument/with/555330293), so I’ll just copy and slightly adapt what I said there

> [@](#):
>
> Yes, it’s expected. There’s two separate parser quirks you need to know here:
> 
> 1. `for i = 1:2` is another way to write `for i in 1:2` (and in fact the former is what the parser lowers to I think because Stefan always liked the `=` syntax more, not sure of the exact history):
> 
> ```julia-auto
> julia> [x+1 for x = 1:2]
> 2-element Vector{Int64}:
> 2
> 3
> 
> ```
> 
> 1. Julia supports multidimensional comprehensions:
> 
> ```julia-auto
> julia> [(x, y) for x in 1:3, y in (:a, :b, :c)]
> 3×3 Matrix{Tuple{Int64, Symbol}}:
> (1, :a) (1, :b) (1, :c)
> (2, :a) (2, :b) (2, :c)
> (3, :a) (3, :b) (3, :c)
> 
> ```
> 
> Putting that together, julia parses your `sum` call as
> 
> ```julia-auto
> generator = (y[i] for i in a_set, init in zero(eltype(y))) # a 2D generator!
> sum(generator)
> 
> ```

This is unfortunately just a nasty, confusing cornercase where our keyword argument syntax overlaps with the generator syntax.

One way you can protect yourself from this is always wrap a generator in parentheses, i.e.

```julia-auto
sum((y[i] for i in a_set), init = zero(eltype(y)))

```

and it’s also good practice to always separate kwargs with a `;`, so you’d then get

```julia-auto
sum((y[i] for i in a_set); init = zero(eltype(y)))

```

* * *

P.S.: This isn’t really that relevant to the problem, but it might be good to know that you actually don’t need to use generators here to avoid allocations, you can also use the 2-argument function version of `sum`, i.e.

```julia-auto
sum(i -> y[i], a_set; init = zero(eltype(y)))

```

---

<div class="post-metadata">

**Author:** ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)\
**Post date:** [November 14, 2025, 12:10pm UTC](https://discourse.julialang.org/t/i-dont-understand-reducing-over-empty-iterators/133870/4 "2025-11-14T12:10:30Z")

</div>

Ha ok that works indeed. Usually, function do not need semicolons before keywords.

---

<div class="post-metadata">

**Author:** ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)\
**Post date:** [November 14, 2025, 12:12pm UTC](https://discourse.julialang.org/t/i-dont-understand-reducing-over-empty-iterators/133870/5 "2025-11-14T12:12:19Z")

</div>

Thanks I understand! I won’t forget it now.

---

<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:** [November 14, 2025, 7:24pm UTC](https://discourse.julialang.org/t/i-dont-understand-reducing-over-empty-iterators/133870/6 "2025-11-14T19:24:36Z")

</div>

While it is correct that oftentimes you don’t _need_ a semicolon, I think it is good style to nonetheless use a semicolon evertime. It takes a short while to get used to but then you will never have to think about it again and it actually saves you in instances like this. Personally I always use the semicolon and it recommend in 2 of the largest style guides

> **[GitHub - JuliaDiff/BlueStyle: A Julia style guide that lives in a blue world](https://github.com/JuliaDiff/BlueStyle?tab=readme-ov-file#keyword-arguments)**
>
> A Julia style guide that lives in a blue world

> **[GitHub - SciML/SciMLStyle: A style guide for stylish Julia developers](https://github.com/SciML/SciMLStyle?tab=readme-ov-file#functions)**
>
> A style guide for stylish Julia developers
