# Between a rock and a crazy place

## Lazy evaluation in go

17 Jul 2015

tl;dr: I did lazy evaluation in go

A small pattern that is usefull for some algorithms is lazy evaluation. Haskell is famous for making extensive use of it. One way to emulate goroutine-safe lazy evaluation is using closures and the sync-package:

type LazyInt func() int

func Make(f func() int) LazyInt {
var v int
var once sync.Once
return func() int {
once.Do(func() {
v = f()
f = nil // so that f can now be GC'ed
})
return v
}
}

func main() {
n := Make(func() { return 23 }) // Or something more expensive…
fmt.Println(n())                // Calculates the 23
fmt.Println(n() + 42)           // Reuses the calculated value
}


This is not the fastest possible code, but it already has less overhead than one would think (and it is pretty simple to deduce a faster implementation from this). I have implemented a simple command, that generates these implementations (or rather, more optimized ones based on the same idea) for different types.

This is of course just the simplest use-case for lazynes. In practice, you might also want Implementations of Expressions

func LazyAdd(a, b LazyInt) LazyInt {
return Make(func() { return a() + b() })
}


or lazy slices (slightly more complicated to implement, but possible) but I left that for a later improvement of the package (plus, it makes the already quite big API even bigger) :)