# Skipping parts of a for loop in the first iteration

**URL:** https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252
**Category:** General Usage
**Created:** [October 12, 2018, 7:54pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252 "2018-10-12T19:54:53Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [October 12, 2018, 7:54pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/1 "2018-10-12T19:54:53Z")

</div>

I crave a macro that does

```julia
@for x in iter begin 
    dosomethings()
    if $first_iteration
        y = dothings_differently(x)
    else
        y = dothings(y, x)
    end
    dootherthings()
end

```

branch free by rewriting into a preamble and a while loop.  
It’s slightly above my head, any input welcome.

Edit: I should say, my hope is of course that someone else now wants this so much that they have to implement it.

---

<div class="post-metadata">

### Author: ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)
#### Post date: [October 12, 2018, 8:30pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/2 "2018-10-12T20:30:16Z")

</div>

Something like this?

```julia
using MacroTools: postwalk, @capture

macro metafor(loop)
    firstexpr = nothing
    loop = postwalk(loop) do x
        if @capture(x, for idx_ ∈ iter_ inner_ end)
            quote
                for $idx ∈ $iter
                    $idx == first($iter) && continue
                    $inner
                end
            end
        elseif @capture(x, @first(y_))
            firstexpr = y
            nothing
        else
            x
        end
    end
    esc(quote
        $firstexpr
        $loop
    end)
end

```

which gives

```julia
@metafor for i ∈ 1:5
    @first println("first!")
    println("not first")
end
>>>
first!
not first
not first
not first 
not first

```

It’s a little messy and can certainly be improved on, but taht should give you a rough idea of a possible implementation. (Of course you could do endless variations based on which code you want to execute in which iteration.)

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [October 12, 2018, 8:45pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/3 "2018-10-12T20:45:57Z")

</div>

Thank you I will study this. Now I now why there is `MacroTools`. My failing attempt without it is already more than twice as much code.

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [October 12, 2018, 9:09pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/4 "2018-10-12T21:09:09Z")

</div>

I can contribute now a nice `quote` body:

```julia
quote let ϕ = iterate($iter)
        while ϕ != nothing
            $i, st = ϕ
            $(stms1...)
            while true
                ϕ = iterate($iter, st)
                ϕ != nothing && break
                $i, st = ϕ
                $(stms...)
            end
            break
        end
    end end

```

Edit: Small fix, still something goes wrong if one uses `continue` in the first iteration.

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [October 12, 2018, 9:37pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/5 "2018-10-12T21:37:41Z")

</div>

Alas, I carve this as well but lack the macro-fu to help. Please post here the solution and a MWE once you’re content. Thanks!!!

---

<div class="post-metadata">

### Author: ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)
#### Post date: [October 12, 2018, 10:20pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/6 "2018-10-12T22:20:43Z")

</div>

Writing macros in Julia without the aid of MacroTools is indeed a nightmare. It really should have been in the stdlib. Once you mess around with MacroTools a bit, you’ll probably find it much easier. Just remember: you should think of a macro as a simple syntax transformation and you should always think about how you would write your code _without_ a macro (i.e. the desired output of the macro) before you start writing the macro.

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [October 13, 2018, 9:18am UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/8 "2018-10-13T09:18:12Z")

</div>

Heureka!

```julia
"""
    @unroll1 for-loop

Unroll the first iteration of a `for`-loop.
Set `$first` to true in the first iteration.

Example:
    @unroll1 for i in 1:10
        if $first
            a, state = iterate('A':'Z')
        else
            a, state = iterate('A':'Z', state)
        end
        println(i => a)
    end
"""
macro unroll1(expr)
    @assert expr isa Expr
    @assert expr.head == :for
    iterspec = expr.args[1]

    @assert iterspec isa Expr
    @assert iterspec.head == :(=)
    i = iterspec.args[1]
    iter = iterspec.args[2]

    body = expr.args[2]

    body_1 = eval(Expr(:let, :(first = true), Expr(:quote, body)))
    body_i = eval(Expr(:let, :(first = false), Expr(:quote, body)))

    quote
        local st, $i
        @goto enter
        while true
            @goto exit
            @label enter
                ϕ = iterate($iter)
                ϕ === nothing && break
                $i, st = ϕ
                $(body_1)
            @label exit
            while true
                ϕ = iterate($iter, st)
                ϕ === nothing && break
                $i, st = ϕ
                $(body_i)
            end
            break
        end
    end
end

```

---

<div class="post-metadata">

### Author: ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)
#### Post date: [October 13, 2018, 3:18pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/9 "2018-10-13T15:18:17Z")

</div>

Cool macro! My only objection would be that readability is a bit reduced, since developers not familiar with that macro might not understand at first glance what the code is doing.

Another alternative:

```julia
for (i,c) in enumerate('A':'D')
    if i == 1
        print("first")
    else
        print("not first")
    end
    println(" body $c")
end

```

Results in:

```julia
first body A
not first body B
not first body C
not first body D

```

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [April 23, 2019, 8:18pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/10 "2019-04-23T20:18:42Z")

</div>

A debugged version is in `Trajectories.jl`: [https://github.com/mschauer/Trajectories.jl/blob/master/src/unroll1.jl](https://github.com/mschauer/Trajectories.jl/blob/master/src/unroll1.jl)

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [April 24, 2020, 3:06pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/11 "2020-04-24T15:06:21Z")

</div>

I think I also like

```julia
using IterTools: flagfirst

function fsum(f, xs, default)
    local y
    for (isfirst, x) in flagfirst(xs)
        if isfirst
            y = f(x)
        else
            y = y + f(x)
        end
    end
    if @isdefined(y) 
        return y 
    else 
        return default 
    end
end

```

Edit: Handle empty iterators

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 25, 2020, 5:15am UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/12 "2020-04-25T05:15:33Z")

</div>

I am not sure if you are aware of [`IterTools.flagfirst`](https://juliacollections.github.io/IterTools.jl/latest/#flagfirst(xs)-1).

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [April 25, 2020, 5:42am UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/13 "2020-04-25T05:42:57Z")

</div>

Thanks for implementing and pointing out that iterator.

---

<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: [April 25, 2020, 11:16am UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/14 "2020-04-25T11:16:22Z")

</div>

I find it more elegant to use `Iterators.peel` from the stdlib:

```julia
function fsum(f, itr)
    (x, rest) = Iterators.peel(itr)
    s = f(x)
    for x in rest
        s += f(x)
    end
    return s
end

```

---

<div class="post-metadata">

### Author: ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)
#### Post date: [April 25, 2020, 9:11pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/15 "2020-04-25T21:11:53Z")

</div>

> [@DNF](#):
>
> function fsum(f, itr) (x, rest) = Iterators.peel(itr) s = f(x) for x in rest s += f(x) end return s end

That doesn’t help when `itr` is empty though.

---

<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: [April 25, 2020, 9:44pm UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/16 "2020-04-25T21:44:23Z")

</div>

> [@dpsanders](#):
>
> That doesn’t help when `itr` is empty though.

That doesn’t seem to work for `IterTools.flagfirst` either.

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [April 26, 2020, 7:32am UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/17 "2020-04-26T07:32:24Z")

</div>

Surprisingly, that is not a problem… see above.

---

<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: [April 26, 2020, 8:12am UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/18 "2020-04-26T08:12:54Z")

</div>

> [@mschauer](#):
>
> Surprisingly, that is not a problem… see above.

But at this point the code is so long it’s more concise and readable to just do it manually:

```julia
function myfsum(f, xs, default)
    (isfirst, y) = (true, default)
    for x in xs
        if isfirst
            (isfirst, y) = (false, f(x))
        else
            y += f(x)
        end
    end
    return y
end

```

~~Also, there’s a performance issue:~~  
**Edit:** performance is equal after restarting Julia.

```julia
julia> @btime fsum(sin, xs, 0.0) setup=(xs=rand(1000));
  644.010 μs (11000 allocations: 296.88 KiB)

julia> @btime myfsum(sin, xs, 0.0) setup=(xs=rand(1000));
  7.591 μs (0 allocations: 0 bytes)

julia> @btime fsum(sin, xs, 0.0) setup=(xs=rand(0));
  48.977 ns (2 allocations: 32 bytes)

julia> @btime myfsum(sin, xs, 0.0) setup=(xs=rand(0));
  2.892 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [April 26, 2020, 9:20am UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/19 "2020-04-26T09:20:38Z")

</div>

I cannot reproduce your timing problem:

```julia
julia> @btime fsum(sin, xs, 0.0) setup=(xs=rand(1000));
  6.548 μs (0 allocations: 0 bytes)

julia> @btime myfsum(sin, xs, 0.0) setup=(xs=rand(1000));
  6.914 μs (0 allocations: 0 bytes)

julia> versioninfo()
Julia Version 1.3.1
Commit 2d5741174c (2019-12-30 21:36 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin18.6.0)
  CPU: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, skylake)

```

I like your solution though, it’s clear and still uses the quirky initialisation in the loop trick.

---

<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: [April 26, 2020, 9:38am UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/20 "2020-04-26T09:38:47Z")

</div>

> [@mschauer](#):
>
> I cannot reproduce your timing problem:

Yeah, the difference disappeared after a restart. Not sure what happened.

---

<div class="post-metadata">

### Author: ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)
#### Post date: [October 29, 2022, 4:05am UTC](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252/21 "2022-10-29T04:05:07Z")

</div>

Not sure since when, but now we have `Base.Iterators.drop()`:

```julia-repl
julia> VERSION
v"1.8.0"

julia> for i = Iterators.drop(1:10, 5) # drop first five
           println(i)
       end
6
7
8
9
10

```

[Next page](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252.md?page=2)
