AN
INTRODUCTION
TO
FUNCTIONAL PROGRAMMING
IN
GO [REDUX]
ELEANOR MCHUGH
ELEANOR MCHUGH
@feyeleanor
APPLIED PHYSICIST
MISAPPLIED HACKER
EMBEDDED SYSTEMS
VIRTUAL MACHINES
DIGITAL IDENTITY
RUBY
GO
LEANPUB://GONOTEBOOK
A GO DEVELOPER'S NOTEBOOK
▸ teaches Go by exploring code
▸ free tutorial on secure networking
▸ opinionated but not prescriptive
▸ based on a decade of experience
▸ buy once & get all future updates
▸ very irregular update cycle
▸ the only book I'll ever write on Go
LEANPUB://GONOTEBOOK
OO makes code understandable by
encapsulating moving parts.
FP makes code understandable by
minimizing moving parts.
Michael Feathers
@mfeathers
LEANPUB://GONOTEBOOK
FUNCTIONSAS
PARADIGM
FUNCTIONSAS
PARADIGM
A PURE FUNCTION
A PURE FUNCTION
package main
import "os"
func main() {
os.Exit(add(3, 4))
}
func add(x, y int) int {
return x + y
}
A PURE FUNCTION
package main
import "os"
func main() {
os.Exit(add(3, 4))
}
func add(x, y int) int {
return x + y
}
A PURE FUNCTION
package main
import "os"
func main() {
os.Exit(add(3, 4))
}
func add(x int, y int) int {
return x + y
}
A PURE FUNCTION
package main
import "os"
func main() {
os.Exit(add(3, 4))
}
func add(x int, y int) int {
return x + y
}
A PURE FUNCTION
package main
import "os"
func main() {
os.Exit(add(3, 4))
}
func add(x int, y int) int {
return x + y
}
A PURE FUNCTION
package main
import "os"
import "strconv"
func main() {
x, _ := strconv.Atoi(os.Args[1])
y, _ := strconv.Atoi(os.Args[2])
os.Exit(add(x, y))
}
func add(x, y int) int {
return x + y
}
A PURE FUNCTION
package main
import "os"
import "strconv"
func main() {
x, _ := strconv.Atoi(os.Args[1])
y, _ := strconv.Atoi(os.Args[2])
os.Exit(add(x, y))
}
func add(x, y int) int {
return x + y
}
A PURE FUNCTION
package main
import "os"
import "strconv"
func main() {
x, _ := strconv.Atoi(os.Args[1])
y, _ := strconv.Atoi(os.Args[2])
os.Exit(add(x, y))
}
func add(x, y int) int {
return x + y
}
A PURE FUNCTION
package main
import "os"
import "strconv"
func main() {
os.Exit(add(arg(0), arg(1)))
}
func arg(n int) (r int) {
r, _ = strconv.Atoi(os.Args[n + 1])
return
}
func add(x, y int) int {
return x + y
}
A PURE FUNCTION
package main
import "os"
import "strconv"
func main() {
var sum int
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
sum = add(sum, x)
}
os.Exit(sum)
}
func add(x, y int) int {
return x + y
}
A PURE FUNCTION
package main
import "os"
import "strconv"
func main() {
var sum int
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
sum = add(sum, x)
}
os.Exit(sum)
}
func add(x, y int) int {
return x + y
}
FUNCTIONSAS
PARADIGM
BEING IMPURE
BEING IMPURE
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
accumulate(x)
}
os.Exit(y)
}
var y int
func accumulate(x int) {
y += x
}
BEING IMPURE
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
accumulate(x)
}
os.Exit(y)
}
var y int
func accumulate(x int) {
y += x
}
BEING IMPURE
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
accumulate(x)
}
os.Exit(y)
}
var y int
func accumulate(x int) {
y += x
}
BEING IMPURE
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
accumulate(x)
}
os.Exit(y)
}
var y int
func accumulate(x int) {
y += x
}
BEING IMPURE
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a.Add(x)
}
os.Exit(int(a))
}
var a Accumulator
type Accumulator int
func (a *Accumulator) Add(y int) {
*a += Accumulator(y)
}
BEING IMPURE
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a.Add(x)
}
os.Exit(int(a))
}
var a Accumulator
type Accumulator int
func (a *Accumulator) Add(y int) {
*a += Accumulator(y)
}
BEING IMPURE
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a.Add(x)
}
os.Exit(int(a))
}
var a Accumulator
type Accumulator int
func (a *Accumulator) Add(y int) {
*a += Accumulator(y)
}
BEING IMPURE
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a.Add(x)
}
os.Exit(int(a))
}
var a Accumulator
type Accumulator int
func (a Accumulator) Add(y int) {
a += Accumulator(y)
}
FUNCTIONSAS
PARADIGM
FUNCTIONS WITH MEMORY
FUNCTIONS WITH MEMORY
package main
import "os"
import "strconv"
func main() {
a := MakeAccumulator()
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
func MakeAccumulator() func(int) int {
var y int
return func(x int) int {
y += x
return y
}
}
FUNCTIONS WITH MEMORY
package main
import "os"
import "strconv"
func main() {
a := MakeAccumulator()
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
func MakeAccumulator() func(int) int {
var y int
return func(x int) int {
y += x
return y
}
}
FUNCTIONS WITH MEMORY
package main
import "os"
import "strconv"
func main() {
a := MakeAccumulator()
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
func MakeAccumulator() func(int) int {
var y int
return func(x int) int {
y += x
return y
}
}
FUNCTIONS WITH MEMORY
package main
import "os"
import "strconv"
func main() {
a := MakeAccumulator()
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
func MakeAccumulator() func(int) int {
var y int
return func(x int) int {
y += x
return y
}
}
FUNCTIONS WITH MEMORY
package main
import "os"
import "strconv"
func main() {
a := MakeAccumulator()
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
func MakeAccumulator() func(int) int {
var y int
return func(x int) int {
y += x
return y
}
}
FUNCTIONS WITH MEMORY
package main
import "os"
import "strconv"
func main() {
a := MakeAccumulator()
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
type Accumulator func(int) int
func MakeAccumulator() Accumulator {
var y int
return func(x int) int {
y += x
return y
}
}
FUNCTIONSAS
PARADIGM
FUNCTIONS AS OBJECTS
FUNCTIONS AS OBJECTS
package main
import "os"
import "strconv"
func main() {
a := MakeAccumulator()
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a.Int())
}
type Accumulator func(int) int
func MakeAccumulator() Accumulator {
var y int
return func(x int) int {
y += x
return y
}
}
func (a Accumulator) Int() int {
return a(0)
}
FUNCTIONS AS OBJECTS
package main
import "os"
import "strconv"
func main() {
a := MakeAccumulator()
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a.Int())
}
type Accumulator func(int) int
func MakeAccumulator() Accumulator {
var y int
return func(x int) int {
y += x
return y
}
}
func (a Accumulator) Int() int {
return a(0)
}
FUNCTIONS AS OBJECTS
package main
import "os"
import "strconv"
func main() {
a := MakeAccumulator()
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a.Add(x)
}
os.Exit(a.Int())
}
type Accumulator func(int) int
func MakeAccumulator() Accumulator {
var y int
return func(x int) int {
y += x
return y
}
}
func (a Accumulator) Int() int {
return a(0)
}
func (a Accumulator) Add(x interface{}) {
switch x := x.(type) {
case int:
a(x)
case Accumulator:
a(x.Value())
}
}
FUNCTIONS AS OBJECTS
package main
import "os"
import "strconv"
func main() {
a := MakeAccumulator()
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a.Add(MakeAccumulator()(x))
}
os.Exit(a.Int())
}
type Accumulator func(int) int
func MakeAccumulator() Accumulator {
var y int
return func(x int) int {
y += x
return y
}
}
func (a Accumulator) Int() int {
return a(0)
}
func (a Accumulator) Add(x interface{}) {
switch x := x.(type) {
case int:
a(x)
case Accumulator:
a(x.Value())
}
}
FUNCTIONS AS OBJECTS
package main
import "os"
import "strconv"
func main() {
a := MakeAccumulator()
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a.Add(MakeAccumulator()(x))
}
os.Exit(a.Int())
}
type Accumulator func(int) int
type Integer interface {
Int() int
}
func MakeAccumulator() Accumulator {
var y int
return func(x int) int {
y += x
return y
}
}
func (a Accumulator) Int() int {
return a(0)
}
func (a Accumulator) Add(x interface{}) {
switch x := x.(type) {
case int:
a(x)
case Integer:
a(x.Int())
}
}
FUNCTIONSIN
MATHEMATICS
COMPUTING FACTORIALS
COMPUTING FACTORIALS
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
FUNCTIONSIN
MATHEMATICS
ITERATING FACTORIALS
ITERATING FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = 1
for ; n > 0; n-- {
r *= n
}
}
return
}
ITERATING FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = 1
for ; n > 0; n-- {
r *= n
}
}
return
}
ITERATING FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = 1
for ; n > 0; n-- {
r *= n
}
}
return
}
ITERATING FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = 1
for ; n > 0; n-- {
r *= n
}
}
return
}
ITERATING FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = 1
for ; n > 0; n-- {
r *= n
}
}
return
}
ITERATING FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = 1
for ; n > 0; n-- {
r *= n
}
}
return
}
ITERATING FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) int {
r := 1
switch {
case n < 0:
panic(n)
case n > 0:
for ; n > 0; n-- {
r *= n
}
}
return r
}
ITERATING FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
ITERATING FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
FUNCTIONSIN
MATHEMATICS
PAINFUL EXCEPTIONS
PAINFUL EXCEPTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
for _, v := range os.Args[1:] {
if x, e := strconv.Atoi(v); e != nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
PAINFUL EXCEPTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
for _, v := range os.Args[1:] {
if x, e := strconv.Atoi(v); e != nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
PAINFUL EXCEPTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
for _, v := range os.Args[1:] {
if x, e := strconv.Atoi(v); e == nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
PAINFUL EXCEPTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
for _, v := range os.Args[1:] {
if x, e := strconv.Atoi(v); e == nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
PAINFUL EXCEPTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
for _, v := range os.Args[1:] {
if x, e := strconv.Atoi(v); e == nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
PAINFUL EXCEPTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
for _, v := range os.Args[1:] {
if x, e := strconv.Atoi(v); e == nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
PAINFUL EXCEPTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
if x, e := strconv.Atoi(v); e == nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
FUNCTIONSIN
MATHEMATICS
HIGHER ORDER FUNCTIONS
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
func() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
if x, e := strconv.Atoi(v); e == nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}()
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
func() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
if x, e := strconv.Atoi(v); e == nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}()
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
func() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
if x, e := strconv.Atoi(v); e == nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}()
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
func() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
if x, e := strconv.Atoi(v); e == nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}()
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
SafeExecute(func(i int) {
Printf("%v!: %vn", i, Factorial(i))
})(v)
}
}
func SafeExecute(f func(int)) func(string) {
return func(v string) {
defer func() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}()
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
SafeExecute(func(i int) {
Printf("%v!: %vn", i, Factorial(i))
})(v)
}
}
func SafeExecute(f func(int)) func(string) {
return func(v string) {
defer func() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}()
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
SafeExecute(func(i int) {
Printf("%v!: %vn", i, Factorial(i))
})(v)
}
}
func SafeExecute(f func(int)) func(string) {
return func(v string) {
defer func() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}()
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
SafeExecute(func(i int) {
Printf("%v!: %vn", i, Factorial(i))
})(v)
}
}
func SafeExecute(f func(int)) func(string) {
return func(v string) {
defer func() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}()
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
var errors int
f := func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}
for _, v := range os.Args[1:] {
if !SafeExecute(f)(v) {
errors++
}
}
os.Exit(errors)
}
func SafeExecute(f func(int)) func(string) bool {
return func(v string) (r bool) {
defer func() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}()
if x, e := strconv.Atoi(v); e == nil {
f(x)
r = true
} else {
panic(v)
}
return
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
var errors int
f := func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}
for _, v := range os.Args[1:] {
if !SafeExecute(f)(v) {
errors++
}
}
os.Exit(errors)
}
func SafeExecute(f func(int)) func(string) bool {
return func(v string) (r bool) {
defer func() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}()
if x, e := strconv.Atoi(v); e == nil {
f(x)
r = true
} else {
panic(v)
}
return
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
var errors int
f := func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}
for _, v := range os.Args[1:] {
if !SafeExecute(f)(v) {
errors++
}
}
os.Exit(errors)
}
func SafeExecute(f func(int)) func(string) bool {
return func(v string) (r bool) {
defer func() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}()
if x, e := strconv.Atoi(v); e == nil {
f(x)
r = true
} else {
panic(v)
}
return
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
var errors int
f := func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}
for _, v := range os.Args[1:] {
if !SafeExecute(f)(v) {
errors++
}
}
os.Exit(errors)
}
func SafeExecute(f func(int)) func(string) bool {
return func(v string) (r bool) {
defer func() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}()
if x, e := strconv.Atoi(v); e == nil {
f(x)
r = true
} else {
panic(v)
}
return
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
var errors int
for _, v := range os.Args[1:] {
SafeExecute(
func(i int) {
Printf("%v!: %vn", i, Factorial(i))
},
func() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
errors++
}
},
)(v)
}
os.Exit(errors)
}
func SafeExecute(f func(int), e func()) func(string) {
return func(v string) {
defer e()
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
HIGHER ORDER FUNCTIONS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
var errors int
for _, v := range os.Args[1:] {
SafeExecute(
func(i int) {
Printf("%v!: %vn", i, Factorial(i))
},
func() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
errors++
}
},
)(v)
}
os.Exit(errors)
}
func SafeExecute(f func(int), e func()) func(string) {
return func(v string) {
defer e()
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
FUNCTIONSIN
MATHEMATICS
CURRYING
CURRYING
CURRYING
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
OnPanicFor(UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}), PrintErrorMessage)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanicFor(f, e func()) {
defer e()
f()
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
CURRYING
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
OnPanicFor(UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}), PrintErrorMessage)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanicFor(f, e func()) {
defer e()
f()
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
CURRYING
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
OnPanicFor(UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}), PrintErrorMessage)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanicFor(f, e func()) {
defer e()
f()
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
CURRYING
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
OnPanicFor(UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}), PrintErrorMessage)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanicFor(f, e func()) {
defer e()
f()
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
CURRYING
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
OnPanicFor(UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}), PrintErrorMessage)()
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanicFor(f, e func()) func() {
return func() {
defer e()
f()
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
CURRYING
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
OnPanicFor(UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}), PrintErrorMessage)()
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanicFor(f, e func()) func() {
return func() {
defer e()
f()
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
CURRYING
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
CURRYING
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
CURRYING
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
CURRYING
package main
import . "fmt"
import "os"
import "strconv"
func main() {
p := OnPanic(PrintErrorMessage)
for _, v := range os.Args[1:] {
p(UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
if n < 0 {
panic(n)
}
for r = 1; n > 0; n-- {
r *= n
}
return
}
FUNCTIONSIN
MATHEMATICS
RECURSION
RECURSION
package main
func main() {
main()
}
RECURSION
package main
func main() {
main()
}
RECURSION
package main
func main() {
main()
}
RECURSION
package main
func main() {
defer func() {
recover()
}
main()
}
RECURSION
package main
import "os"
import"strconv"
var limit int
func init() {
if x, e := strconv.Atoi(os.Args[1]); e == nil {
limit = x
}
}
func main() {
limit--
if limit > 0 {
main()
}
}
RECURSION
package main
import "os"
import"strconv"
var limit int
func init() {
if x, e := strconv.Atoi(os.Args[1]); e == nil {
limit = x
}
}
func main() {
limit--
if limit > 0 {
main()
}
}
RECURSION
package main
import "os"
import"strconv"
var limit int
func init() {
if x, e := strconv.Atoi(os.Args[1]); e == nil {
limit = x
}
}
func main() {
limit--
if limit > 0 {
main()
}
}
RECURSION
package main
import "os"
import"strconv"
var limit int
func init() {
if x, e := strconv.Atoi(os.Args[1]); e == nil {
limit = x
}
}
func main() {
limit--
if limit > 0 {
main()
}
}
FUNCTIONSIN
MATHEMATICS
RECURSIVE FACTORIALS
RECURSIVE FACTORIALS
RECURSIVE FACTORIALS
RECURSIVE FACTORIALS
RECURSIVE FACTORIALS
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = 1
for ; n > 0; n-- {
r *= n
}
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = 1
for ; n > 0; n-- {
r *= n
}
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = 1
for ; n > 0; n-- {
r *= n
}
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
x, _ := strconv.Atoi(os.Args[1])
Printf("%v!: %vn", x, Factorial(x))
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
defer func() {
if x := recover(); x != nil {
Println("no factorial")
}
}()
for _, v := range os.Args[1:] {
if x, e := strconv.Atoi(v); e != nil {
Printf("%v!: %vn", x, Factorial(x))
} else {
panic(v)
}
}
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func Each(s []string, f func(string)) {
for _, v := range s {
f(v)
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func Each(s []string, f func(string)) {
for _, v := range s {
f(v)
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func Each(s []string, f func(string)) {
for _, v := range s {
f(v)
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
return
}
RECURSIVE FACTORIALS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func Factorial(n int) (r int) {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
return
}
FUNCTIONSIN
MATHEMATICS
CACHING RESULTS
CACHING RESULTS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
var cache map[int] int = make(map[int] int)
func Factorial(n int) (r int) {
if r = cache[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
cache[n] = r
}
return
}
CACHING RESULTS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
var cache map[int] int = make(map[int] int)
func Factorial(n int) (r int) {
if r = cache[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
cache[n] = r
}
return
}
CACHING RESULTS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
var cache map[int] int = make(map[int] int)
func Factorial(n int) (r int) {
if r = cache[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
cache[n] = r
}
return
}
CACHING RESULTS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
var cache map[int] int = make(map[int] int)
func Factorial(n int) (r int) {
if r = cache[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
cache[n] = r
}
return
}
CACHING RESULTS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, Factorial(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
var cache map[int] int = make(map[int] int)
func Factorial(n int) (r int) {
if r = cache[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * Factorial(n - 1)
}
cache[n] = r
}
return
}
CACHING RESULTS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
c := make(Cache)
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, c.Factorial(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
type Cache map[int] int
func (c Cache) Factorial(n int) (r int) {
if r = c[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * c.Factorial(n - 1)
}
c[n] = r
}
return
}
CACHING RESULTS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
c := make(Cache)
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, c.Factorial(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
type Cache map[int] int
func (c Cache) Factorial(n int) (r int) {
if r = c[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * c.Factorial(n - 1)
}
c[n] = r
}
return
}
CACHING RESULTS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
f := MakeFactorial()
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, f(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func MakeFactorial() (f func(int) int) {
c := make(map[int] int)
return func(n int) (r int) {
if r = c[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * f(n - 1)
}
c[n] = r
}
return
}
}
CACHING RESULTS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
f := MakeFactorial()
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, f(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func MakeFactorial() (f func(int) int) {
c := make(map[int] int)
return func(n int) (r int) {
if r = c[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * f(n - 1)
}
c[n] = r
}
return
}
}
CACHING RESULTS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
f := MakeFactorial()
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, f(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func MakeFactorial() (f func(int) int) {
c := make(map[int] int)
return func(n int) (r int) {
if r = c[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * f(n - 1)
}
c[n] = r
}
return
}
}
CACHING RESULTS
package main
import . "fmt"
import "os"
import "strconv"
func main() {
f := MakeFactorial()
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, f(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func MakeFactorial() (f func(int) int) {
c := make(map[int] int)
return func(n int) (r int) {
if r = c[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * f(n - 1)
}
c[n] = r
}
return
}
}
RECURSION THROUGH COMBINATION
package main
import . "fmt"
import "os"
import "strconv"
func main() {
f := MakeFactorial()
Each(os.Args[1:], func(v string) {
OnPanic(PrintErrorMessage)(
UseNumericParam(v, func(i int) {
Printf("%v!: %vn", i, f(i))
}))
})
}
func PrintErrorMessage() {
if x := recover(); x != nil {
Printf("no defined value for %vn", x)
}
}
func UseNumericParam(v string, f func(i int)) func() {
return func() {
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
func Each(s []string, f func(string)) {
if len(s) > 0 {
f(s[0])
Each(s[1:], f)
}
}
func OnPanic(e func()) func(func()) {
return func(f func()) {
defer e()
f()
}
}
func MakeFactorial() (f func(int) int) {
c := make(map[int] int)
return func(n int) (r int) {
if r = c[n]; r == 0 {
switch {
case n < 0:
panic(n)
case n == 0:
r = 1
default:
r = n * f(n - 1)
}
c[n] = r
}
return
}
}
An introduction to functional programming with Go [redux]

An introduction to functional programming with Go [redux]

  • 1.
  • 2.
    ELEANOR MCHUGH @feyeleanor APPLIED PHYSICIST MISAPPLIEDHACKER EMBEDDED SYSTEMS VIRTUAL MACHINES DIGITAL IDENTITY RUBY GO
  • 3.
    LEANPUB://GONOTEBOOK A GO DEVELOPER'SNOTEBOOK ▸ teaches Go by exploring code ▸ free tutorial on secure networking ▸ opinionated but not prescriptive ▸ based on a decade of experience ▸ buy once & get all future updates ▸ very irregular update cycle ▸ the only book I'll ever write on Go
  • 4.
  • 5.
    OO makes codeunderstandable by encapsulating moving parts. FP makes code understandable by minimizing moving parts. Michael Feathers @mfeathers LEANPUB://GONOTEBOOK
  • 6.
  • 7.
  • 8.
    A PURE FUNCTION packagemain import "os" func main() { os.Exit(add(3, 4)) } func add(x, y int) int { return x + y }
  • 9.
    A PURE FUNCTION packagemain import "os" func main() { os.Exit(add(3, 4)) } func add(x, y int) int { return x + y }
  • 10.
    A PURE FUNCTION packagemain import "os" func main() { os.Exit(add(3, 4)) } func add(x int, y int) int { return x + y }
  • 11.
    A PURE FUNCTION packagemain import "os" func main() { os.Exit(add(3, 4)) } func add(x int, y int) int { return x + y }
  • 12.
    A PURE FUNCTION packagemain import "os" func main() { os.Exit(add(3, 4)) } func add(x int, y int) int { return x + y }
  • 13.
    A PURE FUNCTION packagemain import "os" import "strconv" func main() { x, _ := strconv.Atoi(os.Args[1]) y, _ := strconv.Atoi(os.Args[2]) os.Exit(add(x, y)) } func add(x, y int) int { return x + y }
  • 14.
    A PURE FUNCTION packagemain import "os" import "strconv" func main() { x, _ := strconv.Atoi(os.Args[1]) y, _ := strconv.Atoi(os.Args[2]) os.Exit(add(x, y)) } func add(x, y int) int { return x + y }
  • 15.
    A PURE FUNCTION packagemain import "os" import "strconv" func main() { x, _ := strconv.Atoi(os.Args[1]) y, _ := strconv.Atoi(os.Args[2]) os.Exit(add(x, y)) } func add(x, y int) int { return x + y }
  • 16.
    A PURE FUNCTION packagemain import "os" import "strconv" func main() { os.Exit(add(arg(0), arg(1))) } func arg(n int) (r int) { r, _ = strconv.Atoi(os.Args[n + 1]) return } func add(x, y int) int { return x + y }
  • 17.
    A PURE FUNCTION packagemain import "os" import "strconv" func main() { var sum int for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) sum = add(sum, x) } os.Exit(sum) } func add(x, y int) int { return x + y }
  • 18.
    A PURE FUNCTION packagemain import "os" import "strconv" func main() { var sum int for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) sum = add(sum, x) } os.Exit(sum) } func add(x, y int) int { return x + y }
  • 19.
  • 20.
    BEING IMPURE package main import"os" import "strconv" func main() { for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) accumulate(x) } os.Exit(y) } var y int func accumulate(x int) { y += x }
  • 21.
    BEING IMPURE package main import"os" import "strconv" func main() { for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) accumulate(x) } os.Exit(y) } var y int func accumulate(x int) { y += x }
  • 22.
    BEING IMPURE package main import"os" import "strconv" func main() { for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) accumulate(x) } os.Exit(y) } var y int func accumulate(x int) { y += x }
  • 23.
    BEING IMPURE package main import"os" import "strconv" func main() { for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) accumulate(x) } os.Exit(y) } var y int func accumulate(x int) { y += x }
  • 24.
    BEING IMPURE package main import"os" import "strconv" func main() { for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a.Add(x) } os.Exit(int(a)) } var a Accumulator type Accumulator int func (a *Accumulator) Add(y int) { *a += Accumulator(y) }
  • 25.
    BEING IMPURE package main import"os" import "strconv" func main() { for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a.Add(x) } os.Exit(int(a)) } var a Accumulator type Accumulator int func (a *Accumulator) Add(y int) { *a += Accumulator(y) }
  • 26.
    BEING IMPURE package main import"os" import "strconv" func main() { for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a.Add(x) } os.Exit(int(a)) } var a Accumulator type Accumulator int func (a *Accumulator) Add(y int) { *a += Accumulator(y) }
  • 27.
    BEING IMPURE package main import"os" import "strconv" func main() { for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a.Add(x) } os.Exit(int(a)) } var a Accumulator type Accumulator int func (a Accumulator) Add(y int) { a += Accumulator(y) }
  • 28.
  • 29.
    FUNCTIONS WITH MEMORY packagemain import "os" import "strconv" func main() { a := MakeAccumulator() for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a(x) } os.Exit(a(0)) } func MakeAccumulator() func(int) int { var y int return func(x int) int { y += x return y } }
  • 30.
    FUNCTIONS WITH MEMORY packagemain import "os" import "strconv" func main() { a := MakeAccumulator() for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a(x) } os.Exit(a(0)) } func MakeAccumulator() func(int) int { var y int return func(x int) int { y += x return y } }
  • 31.
    FUNCTIONS WITH MEMORY packagemain import "os" import "strconv" func main() { a := MakeAccumulator() for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a(x) } os.Exit(a(0)) } func MakeAccumulator() func(int) int { var y int return func(x int) int { y += x return y } }
  • 32.
    FUNCTIONS WITH MEMORY packagemain import "os" import "strconv" func main() { a := MakeAccumulator() for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a(x) } os.Exit(a(0)) } func MakeAccumulator() func(int) int { var y int return func(x int) int { y += x return y } }
  • 33.
    FUNCTIONS WITH MEMORY packagemain import "os" import "strconv" func main() { a := MakeAccumulator() for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a(x) } os.Exit(a(0)) } func MakeAccumulator() func(int) int { var y int return func(x int) int { y += x return y } }
  • 34.
    FUNCTIONS WITH MEMORY packagemain import "os" import "strconv" func main() { a := MakeAccumulator() for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a(x) } os.Exit(a(0)) } type Accumulator func(int) int func MakeAccumulator() Accumulator { var y int return func(x int) int { y += x return y } }
  • 35.
  • 36.
    FUNCTIONS AS OBJECTS packagemain import "os" import "strconv" func main() { a := MakeAccumulator() for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a(x) } os.Exit(a.Int()) } type Accumulator func(int) int func MakeAccumulator() Accumulator { var y int return func(x int) int { y += x return y } } func (a Accumulator) Int() int { return a(0) }
  • 37.
    FUNCTIONS AS OBJECTS packagemain import "os" import "strconv" func main() { a := MakeAccumulator() for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a(x) } os.Exit(a.Int()) } type Accumulator func(int) int func MakeAccumulator() Accumulator { var y int return func(x int) int { y += x return y } } func (a Accumulator) Int() int { return a(0) }
  • 38.
    FUNCTIONS AS OBJECTS packagemain import "os" import "strconv" func main() { a := MakeAccumulator() for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a.Add(x) } os.Exit(a.Int()) } type Accumulator func(int) int func MakeAccumulator() Accumulator { var y int return func(x int) int { y += x return y } } func (a Accumulator) Int() int { return a(0) } func (a Accumulator) Add(x interface{}) { switch x := x.(type) { case int: a(x) case Accumulator: a(x.Value()) } }
  • 39.
    FUNCTIONS AS OBJECTS packagemain import "os" import "strconv" func main() { a := MakeAccumulator() for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a.Add(MakeAccumulator()(x)) } os.Exit(a.Int()) } type Accumulator func(int) int func MakeAccumulator() Accumulator { var y int return func(x int) int { y += x return y } } func (a Accumulator) Int() int { return a(0) } func (a Accumulator) Add(x interface{}) { switch x := x.(type) { case int: a(x) case Accumulator: a(x.Value()) } }
  • 40.
    FUNCTIONS AS OBJECTS packagemain import "os" import "strconv" func main() { a := MakeAccumulator() for _, v := range os.Args[1:] { x, _ := strconv.Atoi(v) a.Add(MakeAccumulator()(x)) } os.Exit(a.Int()) } type Accumulator func(int) int type Integer interface { Int() int } func MakeAccumulator() Accumulator { var y int return func(x int) int { y += x return y } } func (a Accumulator) Int() int { return a(0) } func (a Accumulator) Add(x interface{}) { switch x := x.(type) { case int: a(x) case Integer: a(x.Int()) } }
  • 41.
  • 42.
  • 43.
    COMPUTING FACTORIALS 0! =1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880
  • 44.
  • 45.
    ITERATING FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = 1 for ; n > 0; n-- { r *= n } } return }
  • 46.
    ITERATING FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = 1 for ; n > 0; n-- { r *= n } } return }
  • 47.
    ITERATING FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = 1 for ; n > 0; n-- { r *= n } } return }
  • 48.
    ITERATING FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = 1 for ; n > 0; n-- { r *= n } } return }
  • 49.
    ITERATING FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = 1 for ; n > 0; n-- { r *= n } } return }
  • 50.
    ITERATING FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = 1 for ; n > 0; n-- { r *= n } } return }
  • 51.
    ITERATING FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) int { r := 1 switch { case n < 0: panic(n) case n > 0: for ; n > 0; n-- { r *= n } } return r }
  • 52.
    ITERATING FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 53.
    ITERATING FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 54.
  • 55.
    PAINFUL EXCEPTIONS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() for _, v := range os.Args[1:] { if x, e := strconv.Atoi(v); e != nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 56.
    PAINFUL EXCEPTIONS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() for _, v := range os.Args[1:] { if x, e := strconv.Atoi(v); e != nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 57.
    PAINFUL EXCEPTIONS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() for _, v := range os.Args[1:] { if x, e := strconv.Atoi(v); e == nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 58.
    PAINFUL EXCEPTIONS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() for _, v := range os.Args[1:] { if x, e := strconv.Atoi(v); e == nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 59.
    PAINFUL EXCEPTIONS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() for _, v := range os.Args[1:] { if x, e := strconv.Atoi(v); e == nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 60.
    PAINFUL EXCEPTIONS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() for _, v := range os.Args[1:] { if x, e := strconv.Atoi(v); e == nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 61.
    PAINFUL EXCEPTIONS package main import. "fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { defer func() { if x := recover(); x != nil { Println("no factorial") } }() if x, e := strconv.Atoi(v); e == nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 62.
  • 63.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { func() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() if x, e := strconv.Atoi(v); e == nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } }() } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 64.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { func() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() if x, e := strconv.Atoi(v); e == nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } }() } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 65.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { func() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() if x, e := strconv.Atoi(v); e == nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } }() } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 66.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { func() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() if x, e := strconv.Atoi(v); e == nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } }() } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 67.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { SafeExecute(func(i int) { Printf("%v!: %vn", i, Factorial(i)) })(v) } } func SafeExecute(f func(int)) func(string) { return func(v string) { defer func() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } }() if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 68.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { SafeExecute(func(i int) { Printf("%v!: %vn", i, Factorial(i)) })(v) } } func SafeExecute(f func(int)) func(string) { return func(v string) { defer func() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } }() if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 69.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { SafeExecute(func(i int) { Printf("%v!: %vn", i, Factorial(i)) })(v) } } func SafeExecute(f func(int)) func(string) { return func(v string) { defer func() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } }() if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 70.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { SafeExecute(func(i int) { Printf("%v!: %vn", i, Factorial(i)) })(v) } } func SafeExecute(f func(int)) func(string) { return func(v string) { defer func() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } }() if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 71.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { var errors int f := func(i int) { Printf("%v!: %vn", i, Factorial(i)) } for _, v := range os.Args[1:] { if !SafeExecute(f)(v) { errors++ } } os.Exit(errors) } func SafeExecute(f func(int)) func(string) bool { return func(v string) (r bool) { defer func() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } }() if x, e := strconv.Atoi(v); e == nil { f(x) r = true } else { panic(v) } return } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 72.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { var errors int f := func(i int) { Printf("%v!: %vn", i, Factorial(i)) } for _, v := range os.Args[1:] { if !SafeExecute(f)(v) { errors++ } } os.Exit(errors) } func SafeExecute(f func(int)) func(string) bool { return func(v string) (r bool) { defer func() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } }() if x, e := strconv.Atoi(v); e == nil { f(x) r = true } else { panic(v) } return } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 73.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { var errors int f := func(i int) { Printf("%v!: %vn", i, Factorial(i)) } for _, v := range os.Args[1:] { if !SafeExecute(f)(v) { errors++ } } os.Exit(errors) } func SafeExecute(f func(int)) func(string) bool { return func(v string) (r bool) { defer func() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } }() if x, e := strconv.Atoi(v); e == nil { f(x) r = true } else { panic(v) } return } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 74.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { var errors int f := func(i int) { Printf("%v!: %vn", i, Factorial(i)) } for _, v := range os.Args[1:] { if !SafeExecute(f)(v) { errors++ } } os.Exit(errors) } func SafeExecute(f func(int)) func(string) bool { return func(v string) (r bool) { defer func() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } }() if x, e := strconv.Atoi(v); e == nil { f(x) r = true } else { panic(v) } return } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 75.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { var errors int for _, v := range os.Args[1:] { SafeExecute( func(i int) { Printf("%v!: %vn", i, Factorial(i)) }, func() { if x := recover(); x != nil { Printf("no defined value for %vn", x) errors++ } }, )(v) } os.Exit(errors) } func SafeExecute(f func(int), e func()) func(string) { return func(v string) { defer e() if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 76.
    HIGHER ORDER FUNCTIONS packagemain import . "fmt" import "os" import "strconv" func main() { var errors int for _, v := range os.Args[1:] { SafeExecute( func(i int) { Printf("%v!: %vn", i, Factorial(i)) }, func() { if x := recover(); x != nil { Printf("no defined value for %vn", x) errors++ } }, )(v) } os.Exit(errors) } func SafeExecute(f func(int), e func()) func(string) { return func(v string) { defer e() if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 77.
  • 78.
  • 79.
    CURRYING package main import ."fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { OnPanicFor(UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) }), PrintErrorMessage) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanicFor(f, e func()) { defer e() f() } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 80.
    CURRYING package main import ."fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { OnPanicFor(UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) }), PrintErrorMessage) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanicFor(f, e func()) { defer e() f() } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 81.
    CURRYING package main import ."fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { OnPanicFor(UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) }), PrintErrorMessage) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanicFor(f, e func()) { defer e() f() } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 82.
    CURRYING package main import ."fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { OnPanicFor(UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) }), PrintErrorMessage) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanicFor(f, e func()) { defer e() f() } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 83.
    CURRYING package main import ."fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { OnPanicFor(UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) }), PrintErrorMessage)() } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanicFor(f, e func()) func() { return func() { defer e() f() } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 84.
    CURRYING package main import ."fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { OnPanicFor(UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) }), PrintErrorMessage)() } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanicFor(f, e func()) func() { return func() { defer e() f() } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 85.
    CURRYING package main import ."fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 86.
    CURRYING package main import ."fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 87.
    CURRYING package main import ."fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 88.
    CURRYING package main import ."fmt" import "os" import "strconv" func main() { p := OnPanic(PrintErrorMessage) for _, v := range os.Args[1:] { p(UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { if n < 0 { panic(n) } for r = 1; n > 0; n-- { r *= n } return }
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
    RECURSION package main func main(){ defer func() { recover() } main() }
  • 94.
    RECURSION package main import "os" import"strconv" varlimit int func init() { if x, e := strconv.Atoi(os.Args[1]); e == nil { limit = x } } func main() { limit-- if limit > 0 { main() } }
  • 95.
    RECURSION package main import "os" import"strconv" varlimit int func init() { if x, e := strconv.Atoi(os.Args[1]); e == nil { limit = x } } func main() { limit-- if limit > 0 { main() } }
  • 96.
    RECURSION package main import "os" import"strconv" varlimit int func init() { if x, e := strconv.Atoi(os.Args[1]); e == nil { limit = x } } func main() { limit-- if limit > 0 { main() } }
  • 97.
    RECURSION package main import "os" import"strconv" varlimit int func init() { if x, e := strconv.Atoi(os.Args[1]); e == nil { limit = x } } func main() { limit-- if limit > 0 { main() } }
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = 1 for ; n > 0; n-- { r *= n } } return }
  • 104.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = 1 for ; n > 0; n-- { r *= n } } return }
  • 105.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = 1 for ; n > 0; n-- { r *= n } } return }
  • 106.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() x, _ := strconv.Atoi(os.Args[1]) Printf("%v!: %vn", x, Factorial(x)) } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } return }
  • 107.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { defer func() { if x := recover(); x != nil { Println("no factorial") } }() for _, v := range os.Args[1:] { if x, e := strconv.Atoi(v); e != nil { Printf("%v!: %vn", x, Factorial(x)) } else { panic(v) } } } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } return }
  • 108.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { for _, v := range os.Args[1:] { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } return }
  • 109.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func Each(s []string, f func(string)) { for _, v := range s { f(v) } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } return }
  • 110.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func Each(s []string, f func(string)) { for _, v := range s { f(v) } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } return }
  • 111.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func Each(s []string, f func(string)) { for _, v := range s { f(v) } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } return }
  • 112.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } return }
  • 113.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } return }
  • 114.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } return }
  • 115.
    RECURSIVE FACTORIALS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func Factorial(n int) (r int) { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } return }
  • 116.
  • 117.
    CACHING RESULTS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } var cache map[int] int = make(map[int] int) func Factorial(n int) (r int) { if r = cache[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } cache[n] = r } return }
  • 118.
    CACHING RESULTS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } var cache map[int] int = make(map[int] int) func Factorial(n int) (r int) { if r = cache[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } cache[n] = r } return }
  • 119.
    CACHING RESULTS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } var cache map[int] int = make(map[int] int) func Factorial(n int) (r int) { if r = cache[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } cache[n] = r } return }
  • 120.
    CACHING RESULTS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } var cache map[int] int = make(map[int] int) func Factorial(n int) (r int) { if r = cache[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } cache[n] = r } return }
  • 121.
    CACHING RESULTS package main import. "fmt" import "os" import "strconv" func main() { Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, Factorial(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } var cache map[int] int = make(map[int] int) func Factorial(n int) (r int) { if r = cache[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * Factorial(n - 1) } cache[n] = r } return }
  • 122.
    CACHING RESULTS package main import. "fmt" import "os" import "strconv" func main() { c := make(Cache) Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, c.Factorial(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } type Cache map[int] int func (c Cache) Factorial(n int) (r int) { if r = c[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * c.Factorial(n - 1) } c[n] = r } return }
  • 123.
    CACHING RESULTS package main import. "fmt" import "os" import "strconv" func main() { c := make(Cache) Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, c.Factorial(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } type Cache map[int] int func (c Cache) Factorial(n int) (r int) { if r = c[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * c.Factorial(n - 1) } c[n] = r } return }
  • 124.
    CACHING RESULTS package main import. "fmt" import "os" import "strconv" func main() { f := MakeFactorial() Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, f(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func MakeFactorial() (f func(int) int) { c := make(map[int] int) return func(n int) (r int) { if r = c[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * f(n - 1) } c[n] = r } return } }
  • 125.
    CACHING RESULTS package main import. "fmt" import "os" import "strconv" func main() { f := MakeFactorial() Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, f(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func MakeFactorial() (f func(int) int) { c := make(map[int] int) return func(n int) (r int) { if r = c[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * f(n - 1) } c[n] = r } return } }
  • 126.
    CACHING RESULTS package main import. "fmt" import "os" import "strconv" func main() { f := MakeFactorial() Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, f(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func MakeFactorial() (f func(int) int) { c := make(map[int] int) return func(n int) (r int) { if r = c[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * f(n - 1) } c[n] = r } return } }
  • 127.
    CACHING RESULTS package main import. "fmt" import "os" import "strconv" func main() { f := MakeFactorial() Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, f(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func MakeFactorial() (f func(int) int) { c := make(map[int] int) return func(n int) (r int) { if r = c[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * f(n - 1) } c[n] = r } return } }
  • 128.
    RECURSION THROUGH COMBINATION packagemain import . "fmt" import "os" import "strconv" func main() { f := MakeFactorial() Each(os.Args[1:], func(v string) { OnPanic(PrintErrorMessage)( UseNumericParam(v, func(i int) { Printf("%v!: %vn", i, f(i)) })) }) } func PrintErrorMessage() { if x := recover(); x != nil { Printf("no defined value for %vn", x) } } func UseNumericParam(v string, f func(i int)) func() { return func() { if x, e := strconv.Atoi(v); e == nil { f(x) } else { panic(v) } } } func Each(s []string, f func(string)) { if len(s) > 0 { f(s[0]) Each(s[1:], f) } } func OnPanic(e func()) func(func()) { return func(f func()) { defer e() f() } } func MakeFactorial() (f func(int) int) { c := make(map[int] int) return func(n int) (r int) { if r = c[n]; r == 0 { switch { case n < 0: panic(n) case n == 0: r = 1 default: r = n * f(n - 1) } c[n] = r } return } }