(2019) An Introduction To Functional Programming With Go
(2019) An Introduction To Functional Programming With Go
AN
INTRODUCTION
TO
FUNCTIONAL PROGRAMMING
IN
GO
APPLIED PHYSICIST
MISAPPLIED HACKER
EMBEDDED SYSTEMS
VIRTUAL MACHINES
DIGITAL IDENTITY
RUBY
GO
C
ELEANOR M HUGH
@feyeleanor
LEANPUB://GONOTEBOOK
A GO DEVELOPER'S NOTEBOOK
▸ teaches Go by exploring code
0: 0
1: 2
2: 4
3: 6
4: 8
THE CONDITIONAL LOOP
IMPERATIVE
PROGRAMMING
THE CONDITIONAL LOOP
package main
import "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
fmt.Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
fmt.Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
fmt.Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
THE CONDITIONAL LOOP
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i := 0; i < len(s); i++ {
Printf("%v: %v\n", i, s[i])
}
}
AN EXCEPTIONAL LOOP
IMPERATIVE
PROGRAMMING
AN EXCEPTIONAL LOOP
package main
import . "fmt"
func main() {
defer func() {
recover()
}()
s := []int{0, 2, 4, 6, 8}
i := 0
for {
Printf("%v: %v\n", i, s[i])
i++
}
}
AN EXCEPTIONAL LOOP
package main
import . "fmt"
func main() {
defer func() {
recover()
}()
s := []int{0, 2, 4, 6, 8}
i := 0
for {
Printf("%v: %v\n", i, s[i])
i++
}
}
AN EXCEPTIONAL LOOP
package main
import . "fmt"
func main() {
defer func() {
recover()
}()
s := []int{0, 2, 4, 6, 8}
i := 0
for {
Printf("%v: %v\n", i, s[i])
i++
}
}
AN EXCEPTIONAL LOOP
package main
import . "fmt"
func main() {
defer func() {
recover()
}()
s := []int{0, 2, 4, 6, 8}
i := 0
for {
Printf("%v: %v\n", i, s[i])
i++
}
}
AN EXCEPTIONAL LOOP
package main
import . "fmt"
func main() {
defer func() {
recover()
}()
s := []int{0, 2, 4, 6, 8}
i := 0
for {
Printf("%v: %v\n", i, s[i])
i++
}
}
AN EXCEPTIONAL LOOP
package main
import . "fmt"
func main() {
defer func() {
recover()
}()
s := []int{0, 2, 4, 6, 8}
i := 0
for {
Printf("%v: %v\n", i, s[i])
i++
}
}
AN EXCEPTIONAL LOOP
package main
import . "fmt"
func main() {
defer func() {
recover()
}()
s := []int{0, 2, 4, 6, 8}
for i := 0; ; i++ {
Printf("%v: %v\n", i, s[i])
i++
}
}
ENUMERABLE RANGES
IMPERATIVE
PROGRAMMING
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %v\n", i, v)
}
}
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %v\n", i, v)
}
}
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %v\n", i, v)
}
}
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %v\n", i, v)
}
}
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %v\n", i, v)
}
}
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %v\n", i, v)
}
}
PROGRAMMING
WITH
FUNCTIONS
ENUMERATION BY FUNCTION
PROGRAMMING
WITH
FUNCTIONS
ENUMERATION BY FUNCTION
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice(0, 2, 4, 6, 8)
}
PROGRAMMING
WITH
FUNCTIONS
ABSTRACTING TYPE
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
PROGRAMMING
WITH
FUNCTIONS
FUNCTIONS AS VALUES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, func(s []int, i int) int {
return s[i]
})
}
PROGRAMMING
WITH
FUNCTIONS
CLOSURES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
PROGRAMMING
WITH
FUNCTIONS
CONCURRENCY
package main
import . "fmt"
func main() {
c := make(chan int)
go func() {
for i := 0; i++; i < 5 {
c <- i * 2
}
close(c)
}()
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go func() {
for i := 0; i++; i < 5 {
c <- i * 2
}
close(c)
}()
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int, 16)
go func() {
for i := 0; i++; i < 5 {
c <- i * 2
}
close(c)
}()
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go func() {
for i := 0; i++; i < 5 {
c <- i * 2
}
close(c)
}()
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go func() {
for i := 0; i++; i < 5 {
c <- i * 2
}
close(c)
}()
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go func() {
for i := 0; i++; i < 5 {
c <- i * 2
}
close(c)
}()
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go func() {
for i := 0; i++; i < 5 {
c <- i * 2
}
close(c)
}()
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go func() {
for _, v := range []int{0, 2, 4, 6, 8} {
c <- v
}
close(c)
}()
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go func() {
for _, v := range []int{0, 2, 4, 6, 8} {
c <- v
}
close(c)
}()
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go func() {
for _, v := range []int{0, 2, 4, 6, 8} {
c <- v
}
close(c)
}()
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go func() {
for _, v := range []int{0, 2, 4, 6, 8} {
c <- v
}
close(c)
}()
print_channel(c)
}
PROGRAMMING
WITH
FUNCTIONS
INFINITE SEQUENCES
package main
import . "fmt"
func main() {
c := make(chan int)
go sequence(c)
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go sequence(c)
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go sequence(c)
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go sequence(c)
print_channel(c)
}
package main
import . "fmt"
func main() {
c := make(chan int)
go sequence(c)
print_channel(c)
}
PROGRAMMING
WITH
FUNCTIONS
WORKING WITH KINDS
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import "reflect"
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import "reflect"
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import "reflect"
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import "reflect"
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import . "reflect"
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import . "reflect"
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import . "reflect"
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import . "reflect"
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import . "reflect"
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
package main
import . "reflect"
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_values(s)
print_values(func(i int) int {
return s[i]
})
}
OBJECTS
TYPES + METHODS = OBJECTS
PROGRAMMING
WITH
OBJECTS
TYPES + METHODS = OBJECTS
package main
import . "fmt"
func main() {
s := IterableSlice{ 0, 2, 4, 6, 8 }
i := 0
s.Each(func(v interface{}) {
Printf("%v: %v\n", i, v)
i++
})
}
package main
import . "fmt"
func main() {
s := IterableSlice{ 0, 2, 4, 6, 8 }
i := 0
s.Each(func(v interface{}) {
Printf("%v: %v\n", i, v)
i++
})
}
package main
import . "fmt"
func main() {
s := IterableSlice{ 0, 2, 4, 6, 8 }
i := 0
s.Each(func(v interface{}) {
Printf("%v: %v\n", i, v)
i++
})
}
package main
import . "fmt"
func main() {
s := IterableSlice{ 0, 2, 4, 6, 8 }
i := 0
s.Each(func(v interface{}) {
Printf("%v: %v\n", i, v)
i++
})
}
package main
import . "fmt"
func main() {
s := IterableSlice{ 0, 2, 4, 6, 8 }
i := 0
s.Each(func(v interface{}) {
Printf("%v: %v\n", i, v)
i++
})
}
PROGRAMMING
WITH
OBJECTS
INTERFACES = POLYMORPHISM
package main
import . "fmt"
func main() {
var s Iterable = IterableSlice{ 0, 2, 4, 6, 8 }
i := 0
s.Each(func(v interface{}) {
Printf("%v: %v\n", i, v)
i++
})
}
package main
import . "fmt"
func main() {
var s Iterable = IterableSlice{ 0, 2, 4, 6, 8 }
i := 0
s.Each(func(v interface{}) {
Printf("%v: %v\n", i, v)
i++
})
}
package main
import . "fmt"
func main() {
var s Iterable = IterableSlice{ 0, 2, 4, 6, 8 }
i := 0
s.Each(func(v interface{}) {
Printf("%v: %v\n", i, v)
i++
})
}
package main
import . "fmt"
func main() {
print_values(IterableLimit(5))
print_values(IterableSlice{ 0, 2, 4, 6, 8 })
}
package main
import . "fmt"
func main() {
print_values(IterableLimit(5))
print_values(IterableSlice{ 0, 2, 4, 6, 8 })
}
package main
import . "fmt"
func main() {
print_values(IterableLimit(5))
print_values(IterableSlice{ 0, 2, 4, 6, 8 })
}
package main
import . "fmt"
func main() {
print_values(IterableLimit(5))
print_values(IterableSlice{ 0, 2, 4, 6, 8 })
}
PROGRAMMING
WITH
OBJECTS
IMMUTABILITY IS A CHOICE
package main
import . "fmt"
func main() {
s := IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
package main
import . "fmt"
func main() {
s := IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
package main
import . "fmt"
func main() {
s := IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
package main
import . "fmt"
func main() {
s := IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
package main
import . "fmt"
func main() {
s := &IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
package main
import . "fmt"
func main() {
s := &IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
PARADIGM
A PURE FUNCTION
FUNCTIONS
AS
PARADIGM
A PURE FUNCTION
package main
import "os"
func main() {
os.Exit(add(3, 4))
}
package main
import "os"
func main() {
os.Exit(add(3, 4))
}
package main
import "os"
func main() {
os.Exit(add(3, 4))
}
package main
import "os"
func main() {
os.Exit(add(3, 4))
}
package main
import "os"
func main() {
os.Exit(add(3, 4))
}
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))
}
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))
}
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))
}
package main
import "os"
import "strconv"
func main() {
os.Exit(add(arg(0), arg(1)))
}
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)
}
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)
}
FUNCTIONS
AS
PARADIGM
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
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
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
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
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
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
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
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
FUNCTIONS
AS
PARADIGM
FUNCTIONS WITH MEMORY
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
package main
import "os"
import "strconv"
func main() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
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))
}
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))
}
FUNCTIONS
AS
PARADIGM
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())
}
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())
}
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
ITERATING FACTORIALS
FUNCTIONS
IN
MATHEMATICS
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
}
FUNCTIONS
IN
MATHEMATICS
MULTIPLE 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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}
}
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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}
}
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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}
}
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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}
}
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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}
}
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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}
}
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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}
}
FUNCTIONS
IN
MATHEMATICS
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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}()
}
}
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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}()
}
}
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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}()
}
}
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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}()
}
}
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
HIGHER ORDER FUNCTIONS
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
HIGHER ORDER FUNCTIONS
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
HIGHER ORDER FUNCTIONS
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
HIGHER ORDER FUNCTIONS
if x, e := strconv.Atoi(v); e == nil {
f(x)
r = true
} else {
panic(v)
}
return
}
}
HIGHER ORDER FUNCTIONS
if x, e := strconv.Atoi(v); e == nil {
f(x)
r = true
} else {
panic(v)
}
return
}
}
HIGHER ORDER FUNCTIONS
if x, e := strconv.Atoi(v); e == nil {
f(x)
r = true
} else {
panic(v)
}
return
}
}
HIGHER ORDER FUNCTIONS
if x, e := strconv.Atoi(v); e == nil {
f(x)
r = true
} else {
panic(v)
}
return
}
}
HIGHER ORDER FUNCTIONS
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
HIGHER ORDER FUNCTIONS
if x, e := strconv.Atoi(v); e == nil {
f(x)
} else {
panic(v)
}
}
}
CURRYING
FUNCTIONS
IN
MATHEMATICS
CURRYING
CURRYING
FUNCTIONS
IN
MATHEMATICS
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"
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"
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"
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"
func init() {
if x, e := strconv.Atoi(os.Args[1]); e == nil {
limit = x
}
}
func main() {
limit--
if limit > 0 {
main()
}
}
RECURSIVE FACTORIALS
FUNCTIONS
IN
MATHEMATICS
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
}
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!: %v\n", x, Factorial(x))
} else {
panic(v)
}
}
}
FUNCTIONS
IN
MATHEMATICS
CACHING RESULTS