CyberSpy

Rantings from a guy with way too much free time

Getting func(y) with Channels

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
}

Pothos - A New Take on Data-Flow Frameworks

2018-01-17 programming Rob Baruch
Data-Flows… like a river In today's post, I thought I'd take a look at and discuss the Pothos toolkit, a work-flow tool that improves upon the design principles of gnuradio and enables real-time data-flow processes for real-time applications. Using a MacBook Pro, an ettus N210 SDR, and an FM-antenna, I'll show how easy it is to build an FM Receiver to listen to your favorite radio stations on your laptop. While it's an expensive way to tune in to your local DJ, it's a great demonstration of how to use this great kit (written by Josh Blum). Continue reading

Crypto 101: A Brief Tour of Practical Crypto in Golang

2017-12-14 programming Rob Baruch
Crypto 101: Golang offers a rich collection of packages supporting cryptographic operations. From a beginner's perspective, maybe too many offerings! I offer up an overview of what's available and an introduction to some practical uses of cryptography in Golang. Implementation details are always critical when discussing crypto. We'll discuss some general implications of making poor choices and how such choices can completely undermine any uses of these tools. What’ in the box? Continue reading

Channel Your Inner Gopher

2017-12-13 programming Rob Baruch
Channeling your Inner Gopher - (Literally) Reflecting upon Channels Many gophers are likely familiar with the communication paradigm, channels. An elegant solution to communicate (uni or bidirectionally) typed information among go-routines. In it's simplest form, we declare as type-valued channel variable, make it, and then send and receive data through it. Easy enough! package main import ( "fmt" ) func main() { var simpleChan chan int = make(chan int) go func(c chan int) { // send important data to the channel c <- 42 close(c) }(simpleChan) // receive data num := <-simpleChan fmt. Continue reading

Wanna learn you some Go? Tutor up over here!

Rob

Go Get Interfaced: Enums in Golang

Golang, Interfaces, and Enums So here's a nice golang idiom that I ran across years ago that I found generally useful. Golang, unlike languages like c doesn't natively support enumerations. Instead, constants typically are used when creating a list of enumerations. But, go is a strongly-typed language, so we can do better than simply using constants - we can type our enumeration with the use of a type declaration. type DogState uint By defining a type for our enumeration, we can consistently pass and return typed-values among our functions operating on our enumeration. Continue reading

Gogo

Here we gogo! Years ago, I wrote an interesting article that I thought might be worth re-posting (and revising) here on my blog. For a while I got into programming in golang and in the early going (pun-alert!), there were a lot of idioms that were not well understood by a noob. One of those paradigms was channels, go-routines, and signals used simultaneously. Taken separately, they are more easily understood. But when taken together, there can be some confusion. Continue reading