Q:

Why panic does not occur?

I have the following code:
package main

import (
    "fmt"
)

func main() {
    primes := []int{2, 3, 5, 7, 11, 13}

    for i, _ := range primes {

        s := i + 1
        fmt.Printf("%v => %v\n", s, primes[s:])

    }
}

and it produces the following values:
1 => [3 5 7 11 13]
2 => [5 7 11 13]
3 => [7 11 13]
4 => [11 13]
5 => [13]
6 => []

The question is, why panic does not occur here, it should be out of range. Why index 6 has an empty slice? 
Is slice like a list in functional programming?

A:

Spec: Slice expressions:

For convenience, any of the indices may be omitted. A missing low index defaults to zero; a missing high index defaults to the length of the sliced operand.
For arrays or strings, the indices are in range if 0 <= low <= high <= len(a), otherwise they are out of range. For slices, the upper index bound is the slice capacity cap(a) rather than the length.

The index goes from 0..len(primes)-1, and so s := i+1 will have len(primes) at max.
And the length is an allowed slice index. primes[s:] has a missing high index, so that defaults to len(primes), and primes[s:len(primes)] is valid, but it will be an empty slice when s == len(primes).
When slicing, the low index is inclusive, and high is exclusive, that's why the length is a valid index: primes[:] = primes[0:len(primes)]. For reasoning, see related questions: What is the idea behind the notation of indices of Go slices?; and In a Go slice, why does s[lo:hi] end at element hi-1?

