# What is the advantage of "foreach(v) do.." over "for i in v..."?

**URL:** https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007
**Category:** New to Julia
**Tags:** for-loop
**Created:** [May 14, 2025, 6:23pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007 "2025-05-14T18:23:09Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![Leon\_Niceday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leon_niceday/32/216710_2.png) [@Leon\_Niceday](https://discourse.julialang.org/u/Leon_Niceday)
#### Post date: [May 14, 2025, 6:23pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/1 "2025-05-14T18:23:09Z")

</div>

This

```julia
julia> let t = 0
           for x in v
               t += x
           end
           t
       end

```

vs

```julia
julia> let t = 0
           foreach(v) do x
               t += x
           end
           t
       end

```

It appears to me that `for` can do the same, is not more verbose, has simpler semantics. What’s the real use of the `foreach do..` idiom then?

EDIT: Sorry, I should have mentioned that before posting, I had read the docs for `for`, `foreach`.  
In case interation is over several containers:

```julia
julia> shorter =1:2; longer= 'a':'c';

julia> foreach(shorter, longer) do x,y
           println(x," and ", y)
       end
1 and a
2 and b

julia> for (x,y) in zip(shorter,longer)
           println(x, " and ", y)
       end
1 and a
2 and b

julia> for i in 1:length(shorter)
           println(shorter[i], " and ", longer[i])
       end
1 and a
2 and b

```

---

<div class="post-metadata">

### Author: ![LeePhillips](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leephillips/32/205514_2.png) [@LeePhillips](https://discourse.julialang.org/u/LeePhillips)
#### Post date: [May 14, 2025, 6:30pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/2 "2025-05-14T18:30:39Z")

</div>

I think your examples show what the difference is. `foreach` is a version of `map` that does not return a result (where you are mapping for the side effects). Just type `?foreach` in the REPL for an explanation.

---

<div class="post-metadata">

### Author: ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)
#### Post date: [May 14, 2025, 7:07pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/3 "2025-05-14T19:07:47Z")

</div>

`foreach` can be more convenient if you already have a function that you want to apply to each element of an iterator. Internally it is simply implemented as the loop. A major disadvantage that it has it that in a scenario like yours, it allocates and therefore is significantly slower than a `for` loop. You have go through some hoops to fix this.

Here is an example showing that the `foreach` variant is much slower than a `for` loop unless one wraps the summation variable in a `Ref`.

```julia
function f1(itr) # for loop
    t = 0
    for x in itr
        t += x
    end
    t
end

function f2(itr) # foreach
    t = 0
    foreach(itr) do x
        t += x
    end
    t
end

function f3(itr) # foreach with Ref
    t = Ref(0)
    foreach(itr) do x
        t[] += x
    end
    t[]
end

```

```julia
julia> using Chairmarks

julia> @b 1:1000 f1(_), f2(_), f3(_)
(20.000 ns, 25.360 μs (1459 allocs: 22.797 KiB), 20.000 ns)

```

---

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [May 14, 2025, 7:18pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/4 "2025-05-14T19:18:57Z")

</div>

One of the key differences I’m aware of is that `foreach` will unroll the loop when given a `Tuple`, which can help e.g. with type instabilities due to heterogeneous elements:

```julia
using BenchmarkTools

function square_all_for!(v::Tuple)
    for x in v
        x .*= 2
    end
end

function square_all_foreach!(v::Tuple)
    foreach(v) do x
        x .= x .^ 2
    end
end

function mean_tuple()
    return (
        ones(Float16, 2),
        ones(Float32, 2),
        ones(Float64, 2),
        ones(ComplexF16, 2),
        ones(ComplexF32, 2),
        ones(ComplexF64, 2)
    )
end

```

```julia
julia> @btime square_all_for!(_v) setup = (_v = mean_tuple());
  2.690 μs (24 allocations: 1.03 KiB)

julia> @btime square_all_foreach!(_v) setup = (_v = mean_tuple());
  99.101 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [May 14, 2025, 8:05pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/5 "2025-05-14T20:05:04Z")

</div>

I try to use most specific tool I can for a job. `for` supports early exit via `break`; `map`/`foreach` doesn’t, so I prefer `foreach` (or something more specific like `reduce`) when I don’t need early exit.

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [May 14, 2025, 8:19pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/6 "2025-05-14T20:19:39Z")

</div>

`foreach` is a fairly bad fit with reduction operations, especially until the infamous issue [performance of captured variables in closures · Issue #15276 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/15276) is solved. My favorite application is

```julia
x = rand(100)
# Print all of the elements.
foreach(println, x)

```

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [May 14, 2025, 8:30pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/7 "2025-05-14T20:30:42Z")

</div>

Similar use case. Suppose you have a collection of vectors and you want to sort each one. Then you can do `foreach(sort!, vectors)`.

---

<div class="post-metadata">

### Author: ![Leon\_Niceday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leon_niceday/32/216710_2.png) [@Leon\_Niceday](https://discourse.julialang.org/u/Leon_Niceday)
#### Post date: [May 14, 2025, 8:44pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/8 "2025-05-14T20:44:39Z")

</div>

Thanks all for the answers.

> [@matthias314](#):
>
> `foreach` can be more convenient if you already have a function that you want to apply to each element of an iterator. Internally it is simply implemented as the loop.

More convenient because:

```julia
foreach(f, collection)

```

looks a bit shorter than:

```julia
for i in collection ; f(i) ; end 

```

?

---

<div class="post-metadata">

### Author: ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)
#### Post date: [May 14, 2025, 9:00pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/9 "2025-05-14T21:00:28Z")

</div>

> [@Leon\_Niceday](#):
>
> More convenient because:
> 
> ```julia
> foreach(f, collection)
> 
> ```
> 
> looks a bit shorter

Yes, that’s what I meant.

---

<div class="post-metadata">

### Author: ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)
#### Post date: [May 14, 2025, 9:11pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/10 "2025-05-14T21:11:25Z")

</div>

> [@jar1](#):
>
> I try to use most specific tool I can for a job.

AKA “rule of least power”.

---

<div class="post-metadata">

### Author: ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)
#### Post date: [May 15, 2025, 7:16pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/11 "2025-05-15T19:16:41Z")

</div>

Another example, beside heterogeneous tuples, where `foreach` and friends (`map`, `foldl` etc.) can be much efficient is collections with complex iteration states.

I am writing a code where I have a kind of collection where iteration must unfold into several nested loops. So, implementing `iterate` means I have to carry on the state of each nested loop, and when I slap a filter on top, the compiler seems to give up and allocate dynamic memory.

`foreach` and friends on such types can be implemented in transducer style. The difference is explained in the Transducers.jl docs here: [Comparison to iterators · Transducers.jl](https://juliafolds.github.io/Transducers.jl/dev/explanation/comparison_to_iterators/)

Another (potential) advantage is that `foreach` does not specify the order of traversing the collection, so that in certain cases it may be implemented to take advantage of various compiler optimization and / or multi-threading.

---

<div class="post-metadata">

### Author: ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)
#### Post date: [May 15, 2025, 7:51pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/12 "2025-05-15T19:51:09Z")

</div>

> [@Vasily\_Pisarev](#):
>
> Another (potential) advantage is that `foreach` does not specify the order of traversing the collection

I believe that’s still in TBD state. I.e., the documentation leaves it underspecified. Some Github issues:

- [Define the output order from `map` · Issue #50857 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/50857)

- [Document/decide ordering guarantees for map · Issue #51395 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/51395)

---

<div class="post-metadata">

### Author: ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)
#### Post date: [May 16, 2025, 1:15pm UTC](https://discourse.julialang.org/t/what-is-the-advantage-of-foreach-v-do-over-for-i-in-v/129007/13 "2025-05-16T13:15:57Z")

</div>

Potential advantage it is then.

Yet, I’d prefer to have `map` and `foreach` with unspecified-order semantics proposed by the OP of the latter issue, maybe as dedicated implementations per @Tamas_Papp 's suggestion in the same issue, just to have a common name for developers to use when they want to implement such semantics.

Right now, I believe, `collect(Iterators.map(f, x))` has a guaranteed execution order with no equivalent for `foreach`.

Actually, ordering of the output is also debatable. Right now I’m working on a data structure for parallel computations, and it has two notions of order, insertion order and iteration order (idea is, it can be treated as ordinary iterable as fallback). For practical purposes, insertion order is the “natural” order for mapping output, but if used in multiple-input `map` with a non-indexed other argument, there’s no other option than iteration order which messes everything up.
