Q:

How to implement pop -> do something -> push for a queue using goroutines

I have a queue and I would like to perform the following operations:

pop the first element
If the element is even, push element +1

This should go on until the queue is empty; furthermore I want to use multiple goroutines at the same time.
I am able to do for a single goroutine, but as soon as I add a while everything goes wrong, since it appears that too many goroutines are created. Even putting a else {return} will not solve the problem. Side question: why not? I get the errors:
syntax error: unexpected semicolon or newline before else
syntax error: unexpected }

Link to Playground
var list = []int{0, 1, 2, 3}

var mutex = &sync.Mutex{}

func pop(out chan int) {
    mutex.Lock()
    element := list[0]
    fmt.Println("element is ", element)
    list = list[1:]
    mutex.Unlock()
    out <- element
}

func push(in chan int) {
    for element := range in {
        if element%2 == 0 {
            mutex.Lock()
            list = append(list, element+1)
            fmt.Println("New list is ", list)
            mutex.Unlock()
        }
    }
}

func main() {
    out := make(chan int)
    fmt.Println("MAIN")

//  for len(list) != 0 {
    go pop(out)
    go push(out)
//}
    time.Sleep(2)
}

A:

A (buffered) channel is a queue, not a stack. Hence pushing and popping don't make sense in that context.
Stacks are LIFO (last in, first out), like travel luggage – you put in last what you need first. Queues are FIFO (first in, first out), like a tube where you push marbles through.
In the context of queues, you're said to enqueue and dequeue elements.
Considering all this, this is what I interpret you'd like to do:

Create a buffered channel (buffered means that it can hold a number of elements, effectively making it a queue).
Then fill it up with a bunch of random numbers
Iterate over it and enqueue again only those that are even, adding 1 to them.

Try to implement this new algorithm.

A:

Multiple problems with your code.

else is always on the same line as if's closing brace. Please read the Spec on this.
time.Sleep takes time.Duration as its argument, which is in nanoseconds. If you want to sleep for 2 seconds, use time.Sleep(2*time.Second).
for range in push is not needed.
Your for for just spawns millions of goroutines over and over. Goroutintes are lightweight, but not free. Add some kind of synchronisation mechanism to control how many goroutines you are running.

Here is a slightly better version. It works, even though using time.Sleep as a synchronisation mechanism is something you should never do.

