# Head and Tail

**URL:** <https://discourse.julialang.org/t/head-and-tail/16479>\
**Category:** General Usage\
**Created:** [October 18, 2018, 2:23am UTC](https://discourse.julialang.org/t/head-and-tail/16479 "2018-10-18T02:23:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jandehaan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jandehaan/32/6805_2.png) [@jandehaan](https://discourse.julialang.org/u/jandehaan)\
**Post date:** [October 18, 2018, 2:23am UTC](https://discourse.julialang.org/t/head-and-tail/16479/1 "2018-10-18T02:23:43Z")

</div>

Is there a function in Julia that returns two items: the first (head) element of an iterator/collection and the remainder (tail?) of that same iterator/collection?

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [October 18, 2018, 2:55am UTC](https://discourse.julialang.org/t/head-and-tail/16479/2 "2018-10-18T02:55:32Z")

</div>

```julia
help?> Base.Iterators.peel
  peel(iter)

  Returns the first element and an iterator over the remaining elements.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> (a, rest) = Iterators.peel("abc");

  julia> a
  'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

  julia> collect(rest)
  2-element Array{Char,1}:
   'b'
   'c'

```

---

<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:** [October 18, 2018, 6:24am UTC](https://discourse.julialang.org/t/head-and-tail/16479/3 "2018-10-18T06:24:10Z")

</div>

I wish it would pass through `nothing` instead though for empty collections, instead of throwing a `BoundsError`.

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [October 18, 2018, 7:09am UTC](https://discourse.julialang.org/t/head-and-tail/16479/4 "2018-10-18T07:09:01Z")

</div>

I suspect this implementation will be inefficient for lisp-style tail recursion on anything but very small collections, as it seems to wrap the tail in an additional layer on each iteration.

```julia
julia> (a, rest) = Iterators.peel("abc")
('a', Base.Iterators.Rest{String,Int64}("abc", 2))

julia> (a, rest) = Iterators.peel(rest)
('b', Base.Iterators.Rest{Base.Iterators.Rest{String,Int64},Int64}(Base.Iterators.Rest{String,Int64}("abc", 2), 3))

julia> (a, rest) = Iterators.peel(rest)
('c', Base.Iterators.Rest{Base.Iterators.Rest{Base.Iterators.Rest{String,Int64},Int64},Int64}(Base.Iterators.Rest{Base.Iterators.Rest{String,Int64},Int64}(Base.Iterators.Rest{String,Int64}("abc", 2), 3), 4))

```

Wouldn’t it have been much more efficient to make the tail a `view` or similar?

Or does Julia have an optimization for repeated application of the same wrapper? (That would be both cool and useful!)

---

<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 18, 2018, 7:30am UTC](https://discourse.julialang.org/t/head-and-tail/16479/5 "2018-10-18T07:30:31Z")

</div>

`peel` predates the new iterator interface, that is maybe the main reason.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [October 18, 2018, 11:15am UTC](https://discourse.julialang.org/t/head-and-tail/16479/6 "2018-10-18T11:15:25Z")

</div>

Yeah, maybe there should be a method

```julia
Iterators.rest(itr::Iterators.Rest, state) = Iterators.Rest(itr.itr, state)

```

so that you get

```julia
julia> x = 1 : 3
1:3

julia> x1, r1 = Iterators.peel(x)
(1, Base.Iterators.Rest{UnitRange{Int64},Int64}(1:3, 1))

julia> x2, r2 = Iterators.peel(r1)
(2, Base.Iterators.Rest{UnitRange{Int64},Int64}(1:3, 2))

julia> x3, r3 = Iterators.peel(r2)
(3, Base.Iterators.Rest{UnitRange{Int64},Int64}(1:3, 3))

```

instead of

```julia
julia> x = 1 : 3
1:3

julia> x1, r1 = Iterators.peel(x)
(1, Base.Iterators.Rest{UnitRange{Int64},Int64}(1:3, 1))

julia> x2, r2 = Iterators.peel(r1)
(2, Base.Iterators.Rest{Base.Iterators.Rest{UnitRange{Int64},Int64},Int64}(Base.Iterators.Rest{UnitRange{Int64},Int64}(1:3, 1), 2))

julia> x3, r3 = Iterators.peel(r2)
(3, Base.Iterators.Rest{Base.Iterators.Rest{Base.Iterators.Rest{UnitRange{Int64},Int64},Int64},Int64}(Base.Iterators.Rest{Base.Iterators.Rest{UnitRange{Int64},Int64},Int64}(Base.Iterators.Rest{UnitRange{Int64},Int64}(1:3, 1), 2), 3))

```

> [@Tamas\_Papp](#):
>
> I wish it would pass through `nothing` instead though for empty collections, instead of throwing a `BoundsError` .

I agree.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [October 18, 2018, 12:43pm UTC](https://discourse.julialang.org/t/head-and-tail/16479/7 "2018-10-18T12:43:47Z")

</div>

`Iterators.Stateful` could kinda be used for this.

---

<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 18, 2018, 2:33pm UTC](https://discourse.julialang.org/t/head-and-tail/16479/8 "2018-10-18T14:33:15Z")

</div>

With the new range of zero-costs abstractions would be theoretically an iterator interface possible where `state` is just a regular iterator?

```julia
for i in 1:10  
     println(i)
end

```

lowers to

```julia
_iterate(u::UnitRange) = u.start <= u.stop ? (u.start, u.start+1:u.stop) : nothing 

r = 1:10
while true
    ϕ = _iterate(r)
    ϕ === nothing && break
    el, r = ϕ
    println(el)
end

```

Seems so:

```julia
struct LightRange # Range has a construction cost
    start::Int
    stop::Int
end
_iterate(u::LightRange) = u.start <= u.stop ? (u.start, LightRange(u.start+1,u.stop)) : nothing 

using BenchmarkTools
function f1(n) 
    k = 0
    for i in 1:n
        k += i
    end
    k
end

function f2(n) 
    k = 0
    r = LightRange(1,n)
    while true
        ϕ = _iterate(r)
        ϕ === nothing && break
        el, r = ϕ
        k += el
    end
    k
end

julia> @btime f1(10000)

  2.131 ns (0 allocations: 0 bytes)
50005000

julia> @btime f2(10000)
  2.131 ns (0 allocations: 0 bytes)
50005000

```
