One of the things that go lets you do is pass functions around.
I started the year talking about under from the j language. Which lets you 'bookend' some function with another function (a verb) and a function which undoes that function (obverse).
A great example is Pythagoras' theorem:
- You perform some 'pre-processing' on each value (squaring)
- You add all the values up
- You square root the result
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math" | |
) | |
//Setup some types for functions we want to pass around | |
type unaryFloat func(float64) float64 | |
type binaryFloat func(float64, float64) float64 | |
//A wrapper around + that will let us pass it around | |
func passableAdd(x, y float64) float64 { | |
return x + y | |
} | |
//This is the magical under function. | |
//Call some function on each value (verb) | |
//Combine these new values in another function (fn) | |
//Undo the verb (obverse) | |
func under(verb, obverse unaryFloat, fn binaryFloat, x, y float64) float64 { | |
return obverse(fn(verb(x), verb(y))) | |
} | |
//We want to make functions that call math.Pow to an exponent that we specify. | |
//square = makePower(2) | |
//cubing = makePower(3) | |
func makePower(exp float64) func(float64) float64 { | |
f := func(x float64) float64 { | |
return math.Pow(x, exp) | |
} | |
return f | |
} | |
//My favourite demonstration of under. Pythagoras theorem | |
func pythag(x, y float64) float64 { | |
sq := makePower(2) | |
return under(sq, math.Sqrt, passableAdd, x, y) | |
} | |
func main() { | |
fmt.Println(pythag(3, 4)) | |
} |