Skip to content

Instantly share code, notes, and snippets.

View faiface's full-sized avatar

Michal Štrba faiface

View GitHub Profile

Problem: the "context" package

More than a year ago, I wrote a blog post titled Context Should Go Away For Go 2 which received a fair amount of support and response. In said blog post, I described reasons why the "context" package is a bad idea because it's too infectious.

As explained in the blog post, the reason why "context" spreads so much and in such an unhealthy fashion is because it solves the problem of cancellation of long-running procedures.

I promised to follow the blog post (which only complained about the problem) with a solution. Considering the recent progress around Go 2, I decided it's the right time to do the follow up now. So, here it is!

Solution: bake the cancellation into Go 2

Problem: the context package

More than a year ago, I wrote a blog post titled Context Should Go Away For Go 2 which received a fair amount of support and response. In said blog post, I described reasons why the "context" package is a bad idea because it's too infectious.

As explained in the blog post, the reason why "context" spreads so much and in such an unhealthy fashion is because it solves the problem of cancellation of long-running procedures.

I promised to follow the blog post (which only complained about the problem) with a solution. Considering the recent progress around Go 2, I decided it's the right time to do the follow up now. So, here it is.

Solution: bake the cancellation into Go 2

@faiface
faiface / gist:25896a033a04c022af82e5c244970fb3
Created September 30, 2018 21:37
functional or imperative?
record Vars =
count : Int,
sum : Int,
func initial-vars : Vars = Vars 0 0
func main : IO =
start-with initial-vars;
count := 0;
sum := 0;
title date draft
How I built an audio library using the composite pattern and higher-order functions
2017-08-12 16:21:12 +0200
true

Some people say that Go can't express good abstractions. They mostly refer to the lack of generics. That's because in most object-oriented languages, people are used to creating abstractions around types. In Go, the right way is to create abstractions around behaviour using interfaces and higher-order functions. When you follow this principle, you find that Go is very powerful at

BenchmarkMap/1-4 20000000 64.0 ns/op
BenchmarkMap/5-4 20000000 103 ns/op
BenchmarkMap/10-4 10000000 126 ns/op
BenchmarkMap/100-4 10000000 131 ns/op
BenchmarkMap/1000-4 10000000 129 ns/op
BenchmarkContextValue/1-4 10000000 129 ns/op
BenchmarkContextValue/5-4 10000000 199 ns/op
BenchmarkContextValue/10-4 5000000 245 ns/op
BenchmarkContextValue/100-4 1000000 1131 ns/op
BenchmarkContextValue/1000-4 200000 10138 ns/op
package test_test
import (
"context"
"fmt"
"math/rand"
"testing"
)
func BenchmarkMap(b *testing.B) {
package main
import (
"fmt"
"math"
"os"
"time"
"golang.org/x/image/colornames"
package main
import (
"fmt"
"math"
"os"
"time"
"golang.org/x/image/colornames"
package main
import (
"math"
"os"
"time"
"github.com/faiface/beep"
"github.com/faiface/beep/mp3"
"github.com/faiface/beep/speaker"
package main
import (
"os"
"time"
"github.com/faiface/beep"
"github.com/faiface/beep/speaker"
"github.com/faiface/beep/wav"
)