### CyberSpy

Rantings from a guy with way too much free time

# Getting func(y) with Channels

2019-12-10

## Here’s a little golang puzzle

Take a look at the function below that computes a mystery value for the function $f(x)$. Any idea what the function is? Take a close look at the first line where we create a channel. Notice that the channel isn’t some boring int or string channel. No, this is a channel of type func(int, chan int, chan bool). Wait what??? That’s right, this channel takes a function that takes an integer and two channels as function parameters. We define such a function, x, right aftewards.

func mystery(n int) int {

fc := make(chan func(int, chan int, chan bool), 1)

x := func(v int, pipe chan int, done chan bool) {
if v > (n - 1) {
done <- true
}
pipe <- (v)
}

done := make(chan bool, 1)
pipe := make(chan int, n)

fc <- x

go func(fc chan func(int, chan int, chan bool), pipe chan int, done chan bool) {
start := 0
for {
f := <-fc
f(start, pipe, done)
fc <- f
start++
}
}(fc, pipe, done)

<-done

var sigma int = 0
for {
var y int
var ok bool
select {
case y, ok = <-pipe:
sigma += y
default:
fmt.Printf("empty pipe, break\n")
break
}

if ok {
} else {
fmt.Printf("sigma = %d\n", sigma)
break
}
}

return sigma
}


Still stumped on the composition of $f(x)$? Answer:

$$\text{ }f(x) = \sum_{n=0}^n{\frac{n(n+1)}{2}}$$

Bonus question, how would you modify the code above to compute:

$$\text{ }f(x) = \sum_{n=0}^n{\frac{n(n+1)(2n+1)}{6}}$$

hint: we could refactor the code to make a function that transforms our $x$ value.

func mystery(n int, fx func(int) int) int {

fc := make(chan func(int, chan int, chan bool), 1)

x := func(v int, pipe chan int, done chan bool) {
if v > (n - 1) {
done <- true
}
pipe <- (v)
}

done := make(chan bool, 1)
pipe := make(chan int, n)

fc <- x

go func(fc chan func(int, chan int, chan bool), pipe chan int, done chan bool) {
start := 0
for {
f := <-fc
f(start, pipe, done)
fc <- f
start++
}
}(fc, pipe, done)

<-done

var sigma int = 0
for {
var y int
var ok bool
select {
case y, ok = <-pipe:
sigma += fx(y)
default:
fmt.Printf("empty pipe, break\n")
break
}

if ok {
} else {
fmt.Printf("sigma = %d\n", sigma)
break
}
}

return sigma
}