SlideShare una empresa de Scribd logo
1 de 255
Descargar para leer sin conexión
AN
INTRODUCTION
TO
FUNCTIONAL PROGRAMMING
IN
GO
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
IMPERATIVE
PROGRAMMING
A SIMPLE TASK
0: 0
1: 2
2: 4
3: 6
4: 8
IMPERATIVE
PROGRAMMING
THE CONDITIONAL LOOP
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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", i, s[i])
}
}
IMPERATIVE
PROGRAMMING
AN EXCEPTIONAL LOOP
AN EXCEPTIONAL LOOP
package main
import . "fmt"
func main() {
defer func() {
recover()
}()
s := []int{0, 2, 4, 6, 8}
i := 0
for {
Printf("%v: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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: %vn", 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 i := 0; ; i++ {
Printf("%v: %vn", i, s[i])
i++
}
}
IMPERATIVE
PROGRAMMING
ENUMERABLE RANGES
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
ENUMERABLE RANGES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
PROGRAMMINGWITH
FUNCTIONS
PROGRAMMINGWITH
FUNCTIONS
ENUMERATION BY FUNCTION
ENUMERATION BY FUNCTION
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s []int) {
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
ENUMERATION BY FUNCTION
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s []int) {
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
ENUMERATION BY FUNCTION
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s []int) {
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
ENUMERATION BY FUNCTION
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s []int) {
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
ENUMERATION BY FUNCTION
package main
import . "fmt"
func main() {
print_slice(0, 2, 4, 6, 8)
}
func print_slice(s ...int) {
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
PROGRAMMINGWITH
FUNCTIONS
TYPE ABSTRACTION
ABSTRACTING TYPE
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s interface{}) {
for i, v := range s.([]int) {
Printf("%v: %vn", i, v)
}
}
ABSTRACTING TYPE
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s interface{}) {
for i, v := range s.([]int) {
Printf("%v: %vn", i, v)
}
}
ABSTRACTING TYPE
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s interface{}) {
for i, v := range s.([]int) {
Printf("%v: %vn", i, v)
}
}
ABSTRACTING TYPE
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s interface{}) {
if s, ok := s.([]int); ok {
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
}
ABSTRACTING TYPE
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s interface{}) {
if s, ok := s.([]int); ok {
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
}
ABSTRACTING TYPE
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s interface{}) {
if s, ok := s.([]int); ok {
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
}
ABSTRACTING TYPE
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s interface{}) {
if s, ok := s.([]int); ok {
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
}
ABSTRACTING TYPE
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s interface{}) {
switch s := s.(type) {
case []int:
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
}
ABSTRACTING TYPE
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s interface{}) {
switch s := s.(type) {
case []int:
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
}
ABSTRACTING TYPE
package main
import . "fmt"
func main() {
print_slice([]int{0, 2, 4, 6, 8})
}
func print_slice(s interface{}) {
switch s := s.(type) {
case []int:
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
}
PROGRAMMINGWITH
FUNCTIONS
FUNCTIONS AS VALUES
FUNCTIONS AS VALUES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
func element(s []int, i int) int {
return s[i]
}
func print_slice(s []int, f func([]int, int) int {
defer func() {
recover()
}()
for i := 0; ; i++ {
Printf("%v: %vn", i, f(i))
}
}
FUNCTIONS AS VALUES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
func element(s []int, i int) int {
return s[i]
}
func print_slice(s []int, f func([]int, int) int {
defer func() {
recover()
}()
for i := 0; ; i++ {
Printf("%v: %vn", i, f(i))
}
}
FUNCTIONS AS VALUES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
func element(s []int, i int) int {
return s[i]
}
func print_slice(s []int, f func([]int, int) int) {
defer func() {
recover()
}()
for i := 0; ; i++ {
Printf("%v: %vn", i, f(s, i))
}
}
FUNCTIONS AS VALUES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
func element(s []int, i int) int {
return s[i]
}
func print_slice(s []int, f func([]int, int) int) {
defer func() {
recover()
}()
for i := 0; ; i++ {
Printf("%v: %vn", i, f(s, i))
}
}
FUNCTIONS AS VALUES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
func element(s []int, i int) int {
return s[i]
}
func print_slice(s []int, f func([]int, int) int) {
defer func() {
recover()
}()
for i := 0; ; i++ {
Printf("%v: %vn", i, f(s, i))
}
}
FUNCTIONS AS VALUES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(s, element)
}
func element(s []int, i int) int {
return s[i]
}
func print_slice(s []int, f func([]int, int) int) {
defer func() {
recover()
}()
for i := 0; ; i++ {
Printf("%v: %vn", i, f(s, i))
}
}
FUNCTIONS AS VALUES
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]
})
}
func print_slice(s []int, f func([]int, int) int) {
defer func() {
recover()
}()
for i := 0; ; i++ {
Printf("%v: %vn", i, f(s, i))
}
}
PROGRAMMINGWITH
FUNCTIONS
CLOSURES
CLOSURES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
func print_slice(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
}
}
CLOSURES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
func print_slice(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
}
}
CLOSURES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
func print_slice(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
}
}
CLOSURES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
func print_slice(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
}
}
CLOSURES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
func print_slice(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
}
}
CLOSURES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
func print_slice(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
}
}
CLOSURES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
func print_slice(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
}
}
CLOSURES
package main
import . "fmt"
func main() {
s := []int{0, 2, 4, 6, 8}
print_slice(func(i int) int {
return s[i]
})
}
func print_slice(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
}
}
PROGRAMMINGWITH
FUNCTIONS
CONCURRENCY
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)
}
func print_channel(c chan int) (i int) {
for v := range c {
Printf("%v: %vn", i, v)
i++
}
return
}
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)
}
func print_channel(c chan int) (i int) {
for v := range c {
Printf("%v: %vn", i, v)
i++
}
return
}
CONCURRENCY
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)
}
func print_channel(c chan int) (i int) {
for v := range c {
Printf("%v: %vn", i, v)
i++
}
return
}
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)
}
func print_channel(c chan int) (i int) {
for v := range c {
Printf("%v: %vn", i, v)
i++
}
return
}
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)
}
func print_channel(c chan int) (i int) {
for v := range c {
Printf("%v: %vn", i, v)
i++
}
return
}
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)
}
func print_channel(c chan int) (i int) {
for v := range c {
Printf("%v: %vn", i, v)
i++
}
return
}
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)
}
func print_channel(c chan int) (i int) {
for v := range c {
Printf("%v: %vn", i, v)
i++
}
return
}
CONCURRENCY
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)
}
func print_channel(c chan int) (i int) {
for v := range c {
Printf("%v: %vn", i, v)
i++
}
return
}
CONCURRENCY
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)
}
func print_channel(c chan int) (i int) {
for v := range c {
Printf("%v: %vn", i, v)
i++
}
return
}
CONCURRENCY
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)
}
func print_channel(c chan int) (i int) {
for v := range c {
Printf("%v: %vn", i, v)
i++
}
return
}
CONCURRENCY
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)
}
func print_channel(c chan int) (i int) {
for v := range c {
Printf("%v: %vn", i, v)
i++
}
return
}
PROGRAMMINGWITH
FUNCTIONS
INFINITE SEQUENCES
INFINITE SEQUENCES
package main
import . "fmt"
func main() {
c := make(chan int)
go sequence(c)
print_channel(c)
}
func sequence(c chan int) {
for i := 0; ; i++ {
c <- i * 2
}
}
func print_channel(c chan int) {
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, <- c)
}
return
}
INFINITE SEQUENCES
package main
import . "fmt"
func main() {
c := make(chan int)
go sequence(c)
print_channel(c)
}
func sequence(c chan int) {
for i := 0; ; i++ {
c <- i * 2
}
}
func print_channel(c chan int) {
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, <- c)
}
return
}
INFINITE SEQUENCES
package main
import . "fmt"
func main() {
c := make(chan int)
go sequence(c)
print_channel(c)
}
func sequence(c chan int) {
for i := 0; ; i++ {
c <- i * 2
}
}
func print_channel(c chan int) {
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, <- c)
}
return
}
INFINITE SEQUENCES
package main
import . "fmt"
func main() {
c := make(chan int)
go sequence(c)
print_channel(c)
}
func sequence(c chan int) {
for i := 0; ; i++ {
c <- i * 2
}
}
func print_channel(c chan int) {
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, <- c)
}
return
}
INFINITE SEQUENCES
package main
import . "fmt"
func main() {
c := make(chan int)
go sequence(c)
print_channel(c)
}
func sequence(c chan int) {
for i := 0; ; i++ {
c <- i * 2
}
}
func print_channel(c chan int) {
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, <- c)
}
return
}
PROGRAMMINGWITH
FUNCTIONS
WORKING WITH KINDS
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]
})
}
func print_values(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
case []int:
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
}
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]
})
}
func print_values(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
case []int:
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
}
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]
})
}
func print_values(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
case []int:
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
}
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]
})
}
func print_values(s interface{}) {
switch s := s.(type) {
case func(int) int:
for i := 0; i < 5; i++ {
Printf("%v: %vn", i, s(i))
}
case []int:
for i, v := range s {
Printf("%v: %vn", i, v)
}
}
}
WORKING WITH KINDS
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]
})
}
func print_values(s interface{}) {
switch s := reflect.ValueOf(s); s.Kind() {
case reflect.Func:
for i := 0; i < 5; i++ {
p := []reflect.Value{ reflect.ValueOf(i) }
Printf("%v: %vn", i, s.Call(p)[0].Interface())
}
case reflect.Slice:
for i := 0; i < s.Len(); i++ {
Printf("%v: %vn", i, s.Index(i).Interface())
}
}
}
WORKING WITH KINDS
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]
})
}
func print_values(s interface{}) {
switch s := reflect.ValueOf(s); s.Kind() {
case reflect.Func:
for i := 0; i < 5; i++ {
p := []reflect.Value{ reflect.ValueOf(i) }
Printf("%v: %vn", i, s.Call(p)[0].Interface())
}
case reflect.Slice:
for i := 0; i < s.Len(); i++ {
Printf("%v: %vn", i, s.Index(i).Interface())
}
}
}
WORKING WITH KINDS
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]
})
}
func print_values(s interface{}) {
switch s := reflect.ValueOf(s); s.Kind() {
case reflect.Func:
for i := 0; i < 5; i++ {
p := []reflect.Value{ reflect.ValueOf(i) }
Printf("%v: %vn", i, s.Call(p)[0].Interface())
}
case reflect.Slice:
for i := 0; i < s.Len(); i++ {
Printf("%v: %vn", i, s.Index(i).Interface())
}
}
}
WORKING WITH KINDS
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]
})
}
func print_values(s interface{}) {
switch s := reflect.ValueOf(s); s.Kind() {
case reflect.Func:
for i := 0; i < 5; i++ {
p := []reflect.Value{ reflect.ValueOf(i) }
Printf("%v: %vn", i, s.Call(p)[0].Interface())
}
case reflect.Slice:
for i := 0; i < s.Len(); i++ {
Printf("%v: %vn", i, s.Index(i).Interface())
}
}
}
WORKING WITH KINDS
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]
})
}
func print_values(s interface{}) {
switch s := ValueOf(s); s.Kind() {
case Func:
for i := 0; i < 5; i++ {
p := []Value{ ValueOf(i) }
Printf("%v: %vn", i, s.Call(p)[0].Interface())
}
case Slice:
for i := 0; i < s.Len(); i++ {
Printf("%v: %vn", i, s.Index(i).Interface())
}
}
}
WORKING WITH KINDS
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]
})
}
func print_values(s interface{}) {
switch s := ValueOf(s); s.Kind() {
case Func:
for i := 0; i < 5; i++ {
p := []Value{ ValueOf(i) }
Printf("%v: %vn", i, s.Call(p)[0].Interface())
}
case Slice:
for i := 0; i < s.Len(); i++ {
Printf("%v: %vn", i, s.Index(i).Interface())
}
}
}
WORKING WITH KINDS
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]
})
}
func print_values(s interface{}) {
switch s := ValueOf(s); s.Kind() {
case Func:
for i := 0; i < 5; i++ {
p := []Value{ ValueOf(i) }
Printf("%v: %vn", i, s.Call(p)[0].Interface())
}
case Slice:
for i := 0; i < s.Len(); i++ {
Printf("%v: %vn", i, s.Index(i).Interface())
}
}
}
WORKING WITH KINDS
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]
})
}
func print_values(s interface{}) {
defer func() {
recover()
}
switch s := ValueOf(s); s.Kind() {
case Func:
for i := 0; ; i++ {
p := []Value{ ValueOf(i) }
Printf("%v: %vn", i, s.Call(p)[0].Interface())
}
case Slice:
for i := 0; ; i++ {
Printf("%v: %vn", i, s.Index(i).Interface())
}
}
}
WORKING WITH KINDS
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]
})
}
func print_values(s interface{}) {
switch s := ValueOf(s); s.Kind() {
case Func:
for_each(func(i int) {
p := []Value{ ValueOf(i) }
Printf("%v: %vn", i, s.Call(p)[0].Interface())
})
case Slice:
for_each(func(i int) {
Printf("%v: %vn", i, s.Index(i).Interface())
})
}
}
func for_each(f func(int)) (i int) {
defer func() {
recover()
}
for ; ; i++ {
f(i)
}
}
WORKING WITH KINDS
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]
})
}
func print_values(s interface{}) {
switch s := ValueOf(s); s.Kind() {
case Func:
p := make([]Value, 1)
for_each(func(i int) {
p[0] = ValueOf(i)
Printf("%v: %vn", i, s.Call(p)[0].Interface())
})
case Slice:
for_each(func(i int) {
Printf("%v: %vn", i, s.Index(i).Interface())
})
}
}
func for_each(f func(int)) (i int) {
defer func() {
recover()
}
for ; ; i++ {
f(i)
}
}
PROGRAMMINGWITH
OBJECTS
PROGRAMMINGWITH
OBJECTS
TYPES + METHODS = 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: %vn", i, v)
i++
})
}
type IterableSlice []int
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
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: %vn", i, v)
i++
})
}
type IterableSlice []int
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
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: %vn", i, v)
i++
})
}
type IterableSlice []int
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
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: %vn", i, v)
i++
})
}
type IterableSlice []int
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
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: %vn", i, v)
i++
})
}
type IterableSlice []int
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
PROGRAMMINGWITH
OBJECTS
INTERFACES = POLYMORPHISM
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: %vn", i, v)
i++
})
}
type Iterable interface {
Each(func(interface{}))
}
type IterableSlice []int
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
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: %vn", i, v)
i++
})
}
type Iterable interface {
Each(func(interface{}))
}
type IterableSlice []int
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
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: %vn", i, v)
i++
})
}
type Iterable interface {
Each(func(interface{}))
}
type IterableSlice []int
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
INTERFACES = POLYMORPHISM
package main
import . "fmt"
func main() {
print_values(IterableLimit(5))
print_values(IterableSlice{ 0, 2, 4, 6, 8 })
}
func print_values(s Iterable) (i int) {
s.Each(func(v interface{}) {
Printf("%v: %vn", i, v)
i++
})
return i
}
type Iterable interface {
Each(func(interface{}))
}
type IterableLimit int
type IterableSlice []int
func (i IterableLimit) Each(f func(interface{})) {
for v := IterableLimit(0); v < i; v++ {
f(v)
}
}
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
INTERFACES = POLYMORPHISM
package main
import . "fmt"
func main() {
print_values(IterableLimit(5))
print_values(IterableSlice{ 0, 2, 4, 6, 8 })
}
func print_values(s Iterable) (i int) {
s.Each(func(v interface{}) {
Printf("%v: %vn", i, v)
i++
})
return i
}
type Iterable interface {
Each(func(interface{}))
}
type IterableLimit int
type IterableSlice []int
func (i IterableLimit) Each(f func(interface{})) {
for v := IterableLimit(0); v < i; v++ {
f(v)
}
}
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
INTERFACES = POLYMORPHISM
package main
import . "fmt"
func main() {
print_values(IterableLimit(5))
print_values(IterableSlice{ 0, 2, 4, 6, 8 })
}
func print_values(s Iterable) (i int) {
s.Each(func(v interface{}) {
Printf("%v: %vn", i, v)
i++
})
return i
}
type Iterable interface {
Each(func(interface{}))
}
type IterableLimit int
type IterableSlice []int
func (i IterableLimit) Each(f func(interface{})) {
for v := IterableLimit(0); v < i; v++ {
f(v)
}
}
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
INTERFACES = POLYMORPHISM
package main
import . "fmt"
func main() {
print_values(IterableLimit(5))
print_values(IterableSlice{ 0, 2, 4, 6, 8 })
}
func print_values(s Iterable) (i int) {
s.Each(func(v interface{}) {
Printf("%v: %vn", i, v)
i++
})
return i
}
type Iterable interface {
Each(func(interface{}))
}
type IterableLimit int
type IterableSlice []int
func (i IterableLimit) Each(f func(interface{})) {
for v := IterableLimit(0); v < i; v++ {
f(v)
}
}
func (i IterableSlice) Each(f func(interface{})) {
for _, v := range i {
f(v)
}
}
PROGRAMMINGWITH
OBJECTS
IMMUTABILITY IS A CHOICE
IMMUTABILITY IS A CHOICE
package main
import . "fmt"
func main() {
s := IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
func print_values(s Iterable) (i int) {
s.Each(func(v interface{}) {
Printf("%v: %vn", i, v)
i++
})
return i
}
type Iterable interface {
Each(func(interface{}))
}
type IterableRange struct {
start int
step int
limit int
}
func (r IterableRange) Each(f func(interface{})) {
for; r.limit > 0; r.limit-- {
f(r.start)
r.start += r.step
}
}
IMMUTABILITY IS A CHOICE
package main
import . "fmt"
func main() {
s := IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
func print_values(s Iterable) (i int) {
s.Each(func(v interface{}) {
Printf("%v: %vn", i, v)
i++
})
return i
}
type Iterable interface {
Each(func(interface{}))
}
type IterableRange struct {
start int
step int
limit int
}
func (r IterableRange) Each(f func(interface{})) {
for; r.limit > 0; r.limit-- {
f(r.start)
r.start += r.step
}
}
IMMUTABILITY IS A CHOICE
package main
import . "fmt"
func main() {
s := IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
func print_values(s Iterable) (i int) {
s.Each(func(v interface{}) {
Printf("%v: %vn", i, v)
i++
})
return i
}
type Iterable interface {
Each(func(interface{}))
}
type IterableRange struct {
start int
step int
limit int
}
func (r IterableRange) Each(f func(interface{})) {
for; r.limit > 0; r.limit-- {
f(r.start)
r.start += r.step
}
}
IMMUTABILITY IS A CHOICE
package main
import . "fmt"
func main() {
s := IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
func print_values(s Iterable) (i int) {
s.Each(func(v interface{}) {
Printf("%v: %vn", i, v)
i++
})
return i
}
type Iterable interface {
Each(func(interface{}))
}
type IterableRange struct {
start int
step int
limit int
}
func (r IterableRange) Each(f func(interface{})) {
for; r.limit > 0; r.limit-- {
f(r.start)
r.start += r.step
}
}
IMMUTABILITY IS A CHOICE
package main
import . "fmt"
func main() {
s := &IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
func print_values(s Iterable) (i int) {
s.Each(func(v interface{}) {
Printf("%v: %vn", i, v)
i++
})
return i
}
type Iterable interface {
Each(func(interface{}))
}
type IterableRange struct {
start int
step int
limit int
}
func (r IterableRange) Each(f func(interface{})) {
for; r.limit > 0; r.limit-- {
f(r.start)
r.start += r.step
}
}
IMMUTABILITY IS A CHOICE
package main
import . "fmt"
func main() {
s := &IterableRange{ 0, 2, 5 }
print_values(s)
print_values(s)
}
func print_values(s Iterable) (i int) {
s.Each(func(v interface{}) {
Printf("%v: %vn", i, v)
i++
})
return i
}
type Iterable interface {
Each(func(interface{}))
}
type IterableRange struct {
start int
step int
limit int
}
func (r *IterableRange) Each(f func(interface{})) {
for; r.limit > 0; r.limit-- {
f(r.start)
r.start += r.step
}
}
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() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
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() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
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() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
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() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
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() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
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() {
for _, v := range os.Args[1:] {
x, _ := strconv.Atoi(v)
a(x)
}
os.Exit(a(0))
}
var a = MakeAccumulator()
type Accumulator func(int) int
func MakeAccumulator() Accumulator {
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
}
}
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
}
}
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
MULTIPLE FACTORIALS
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!: %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
}
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!: %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
}
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!: %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
}
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!: %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
}
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!: %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
}
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!: %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
}
MULTIPLE FACTORIALS
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)
s}
}()
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
}
}
An introduction to functional programming with go

Más contenido relacionado

La actualidad más candente

Kotlin collections
Kotlin collectionsKotlin collections
Kotlin collectionsMyeongin Woo
 
10〜30分で何となく分かるGo
10〜30分で何となく分かるGo10〜30分で何となく分かるGo
10〜30分で何となく分かるGoMoriyoshi Koizumi
 
Introducción a Elixir
Introducción a ElixirIntroducción a Elixir
Introducción a ElixirSvet Ivantchev
 
Python Performance 101
Python Performance 101Python Performance 101
Python Performance 101Ankur Gupta
 
Implementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & CImplementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & CEleanor McHugh
 
Dts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlinDts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlinAhmad Arif Faizin
 
Un dsl pour ma base de données
Un dsl pour ma base de donnéesUn dsl pour ma base de données
Un dsl pour ma base de donnéesRomain Lecomte
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with PythonHan Lee
 
6. Generics. Collections. Streams
6. Generics. Collections. Streams6. Generics. Collections. Streams
6. Generics. Collections. StreamsDEVTYPE
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?Adam Dudczak
 
FS2 for Fun and Profit
FS2 for Fun and ProfitFS2 for Fun and Profit
FS2 for Fun and ProfitAdil Akhter
 
Python легко и просто. Красиво решаем повседневные задачи
Python легко и просто. Красиво решаем повседневные задачиPython легко и просто. Красиво решаем повседневные задачи
Python легко и просто. Красиво решаем повседневные задачиMaxim Kulsha
 
Go for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionGo for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionEleanor McHugh
 
Programmation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptProgrammation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptLoïc Knuchel
 
20191116 custom operators in swift
20191116 custom operators in swift20191116 custom operators in swift
20191116 custom operators in swiftChiwon Song
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinFabio Collini
 
Python Yield
Python YieldPython Yield
Python Yieldyangjuven
 

La actualidad más candente (20)

Kotlin collections
Kotlin collectionsKotlin collections
Kotlin collections
 
10〜30分で何となく分かるGo
10〜30分で何となく分かるGo10〜30分で何となく分かるGo
10〜30分で何となく分かるGo
 
Introducción a Elixir
Introducción a ElixirIntroducción a Elixir
Introducción a Elixir
 
Python Performance 101
Python Performance 101Python Performance 101
Python Performance 101
 
Implementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & CImplementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & C
 
Dts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlinDts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlin
 
Un dsl pour ma base de données
Un dsl pour ma base de donnéesUn dsl pour ma base de données
Un dsl pour ma base de données
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with Python
 
6. Generics. Collections. Streams
6. Generics. Collections. Streams6. Generics. Collections. Streams
6. Generics. Collections. Streams
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?
 
FS2 for Fun and Profit
FS2 for Fun and ProfitFS2 for Fun and Profit
FS2 for Fun and Profit
 
2 a networkflow
2 a networkflow2 a networkflow
2 a networkflow
 
Python легко и просто. Красиво решаем повседневные задачи
Python легко и просто. Красиво решаем повседневные задачиPython легко и просто. Красиво решаем повседневные задачи
Python легко и просто. Красиво решаем повседневные задачи
 
Go for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionGo for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd edition
 
Programmation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptProgrammation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScript
 
20191116 custom operators in swift
20191116 custom operators in swift20191116 custom operators in swift
20191116 custom operators in swift
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
 
Awt
AwtAwt
Awt
 
Python Yield
Python YieldPython Yield
Python Yield
 
Introduction to Go for Java Programmers
Introduction to Go for Java ProgrammersIntroduction to Go for Java Programmers
Introduction to Go for Java Programmers
 

Similar a An introduction to functional programming with go

going loopy - adventures in iteration with go - Eleanor McHugh - Codemotion M...
going loopy - adventures in iteration with go - Eleanor McHugh - Codemotion M...going loopy - adventures in iteration with go - Eleanor McHugh - Codemotion M...
going loopy - adventures in iteration with go - Eleanor McHugh - Codemotion M...Codemotion
 
Going Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoGoing Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoEleanor McHugh
 
going loopy - adventures in iteration with google go
going loopy - adventures in iteration with google gogoing loopy - adventures in iteration with google go
going loopy - adventures in iteration with google goEleanor McHugh
 
Implementing Software Machines in Go and C
Implementing Software Machines in Go and CImplementing Software Machines in Go and C
Implementing Software Machines in Go and CEleanor McHugh
 
Golang iran - tutorial go programming language - Preliminary
Golang iran - tutorial  go programming language - PreliminaryGolang iran - tutorial  go programming language - Preliminary
Golang iran - tutorial go programming language - Preliminarygo-lang
 
Generics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsGenerics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsEleanor McHugh
 
Python-GTK
Python-GTKPython-GTK
Python-GTKYuren Ju
 
Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Robert Stern
 
Something about Golang
Something about GolangSomething about Golang
Something about GolangAnton Arhipov
 
Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my dayTor Ivry
 
Torchbearersnotebook.blogspot.com program to create a list in python and valu...
Torchbearersnotebook.blogspot.com program to create a list in python and valu...Torchbearersnotebook.blogspot.com program to create a list in python and valu...
Torchbearersnotebook.blogspot.com program to create a list in python and valu...SAKSHISINGH486
 
III MCS python lab (1).pdf
III MCS python lab (1).pdfIII MCS python lab (1).pdf
III MCS python lab (1).pdfsrxerox
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in ScalaHermann Hueck
 
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkelingmobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkelingDevnology
 

Similar a An introduction to functional programming with go (20)

going loopy - adventures in iteration with go - Eleanor McHugh - Codemotion M...
going loopy - adventures in iteration with go - Eleanor McHugh - Codemotion M...going loopy - adventures in iteration with go - Eleanor McHugh - Codemotion M...
going loopy - adventures in iteration with go - Eleanor McHugh - Codemotion M...
 
Going Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoGoing Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google Go
 
going loopy - adventures in iteration with google go
going loopy - adventures in iteration with google gogoing loopy - adventures in iteration with google go
going loopy - adventures in iteration with google go
 
Going Loopy
Going LoopyGoing Loopy
Going Loopy
 
Hello Go
Hello GoHello Go
Hello Go
 
Implementing Software Machines in Go and C
Implementing Software Machines in Go and CImplementing Software Machines in Go and C
Implementing Software Machines in Go and C
 
Golang iran - tutorial go programming language - Preliminary
Golang iran - tutorial  go programming language - PreliminaryGolang iran - tutorial  go programming language - Preliminary
Golang iran - tutorial go programming language - Preliminary
 
lets play with "c"..!!! :):)
lets play with "c"..!!! :):)lets play with "c"..!!! :):)
lets play with "c"..!!! :):)
 
Generics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsGenerics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient Collections
 
Python-GTK
Python-GTKPython-GTK
Python-GTK
 
Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1
 
Something about Golang
Something about GolangSomething about Golang
Something about Golang
 
Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my day
 
Torchbearersnotebook.blogspot.com program to create a list in python and valu...
Torchbearersnotebook.blogspot.com program to create a list in python and valu...Torchbearersnotebook.blogspot.com program to create a list in python and valu...
Torchbearersnotebook.blogspot.com program to create a list in python and valu...
 
III MCS python lab (1).pdf
III MCS python lab (1).pdfIII MCS python lab (1).pdf
III MCS python lab (1).pdf
 
Pnno
PnnoPnno
Pnno
 
goatwork2014
goatwork2014goatwork2014
goatwork2014
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in Scala
 
CHAPTER 6
CHAPTER 6CHAPTER 6
CHAPTER 6
 
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkelingmobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
 

Más de Eleanor McHugh

[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdfEleanor McHugh
 
The Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityThe Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityEleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]Eleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveEleanor McHugh
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionEleanor McHugh
 
An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]Eleanor McHugh
 
Identity & trust in Monitored Spaces
Identity & trust in Monitored SpacesIdentity & trust in Monitored Spaces
Identity & trust in Monitored SpacesEleanor McHugh
 
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignDon't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignEleanor McHugh
 
Don't ask, don't tell the virtues of privacy by design
Don't ask, don't tell   the virtues of privacy by designDon't ask, don't tell   the virtues of privacy by design
Don't ask, don't tell the virtues of privacy by designEleanor McHugh
 
Anonymity, identity, trust
Anonymity, identity, trustAnonymity, identity, trust
Anonymity, identity, trustEleanor McHugh
 
Distributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleDistributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleEleanor McHugh
 
Finding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in goFinding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in goEleanor McHugh
 
Anonymity, trust, accountability
Anonymity, trust, accountabilityAnonymity, trust, accountability
Anonymity, trust, accountabilityEleanor McHugh
 
Implementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & CImplementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & CEleanor McHugh
 
Implementing Software Machines in C and Go
Implementing Software Machines in C and GoImplementing Software Machines in C and Go
Implementing Software Machines in C and GoEleanor McHugh
 
Encrypt all transports
Encrypt all transportsEncrypt all transports
Encrypt all transportsEleanor McHugh
 
Privacy is always a requirement
Privacy is always a requirementPrivacy is always a requirement
Privacy is always a requirementEleanor McHugh
 
Hybrid Cryptography with examples in Ruby and Go
Hybrid Cryptography with examples in Ruby and GoHybrid Cryptography with examples in Ruby and Go
Hybrid Cryptography with examples in Ruby and GoEleanor McHugh
 

Más de Eleanor McHugh (20)

[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf
 
The Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityThe Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data Integrity
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
 
An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]
 
Identity & trust in Monitored Spaces
Identity & trust in Monitored SpacesIdentity & trust in Monitored Spaces
Identity & trust in Monitored Spaces
 
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignDon't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By Design
 
Don't ask, don't tell the virtues of privacy by design
Don't ask, don't tell   the virtues of privacy by designDon't ask, don't tell   the virtues of privacy by design
Don't ask, don't tell the virtues of privacy by design
 
Anonymity, identity, trust
Anonymity, identity, trustAnonymity, identity, trust
Anonymity, identity, trust
 
Distributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleDistributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at Scale
 
Finding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in goFinding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in go
 
Anonymity, trust, accountability
Anonymity, trust, accountabilityAnonymity, trust, accountability
Anonymity, trust, accountability
 
Implementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & CImplementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & C
 
Implementing Software Machines in C and Go
Implementing Software Machines in C and GoImplementing Software Machines in C and Go
Implementing Software Machines in C and Go
 
Encrypt all transports
Encrypt all transportsEncrypt all transports
Encrypt all transports
 
Whispered secrets
Whispered secretsWhispered secrets
Whispered secrets
 
Whispered secrets
Whispered secretsWhispered secrets
Whispered secrets
 
Privacy is always a requirement
Privacy is always a requirementPrivacy is always a requirement
Privacy is always a requirement
 
Hybrid Cryptography with examples in Ruby and Go
Hybrid Cryptography with examples in Ruby and GoHybrid Cryptography with examples in Ruby and Go
Hybrid Cryptography with examples in Ruby and Go
 

Último

10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfryanfarris8
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfVishalKumarJha10
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 

Último (20)

10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 

An introduction to functional programming with go

  • 2. ELEANOR MCHUGH @feyeleanor APPLIED PHYSICIST MISAPPLIED HACKER EMBEDDED SYSTEMS VIRTUAL MACHINES DIGITAL IDENTITY RUBY GO
  • 3. 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
  • 6. A SIMPLE TASK 0: 0 1: 2 2: 4 3: 6 4: 8
  • 8. 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: %vn", i, s[i]) } }
  • 9. 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: %vn", i, s[i]) } }
  • 10. 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: %vn", i, s[i]) } }
  • 11. 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: %vn", i, s[i]) } }
  • 12. 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: %vn", i, s[i]) } }
  • 13. 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: %vn", i, s[i]) } }
  • 14. 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: %vn", i, s[i]) } }
  • 15. 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: %vn", i, s[i]) } }
  • 16. 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: %vn", i, s[i]) } }
  • 17. 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: %vn", i, s[i]) } }
  • 18. 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: %vn", i, s[i]) } }
  • 19. 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: %vn", i, s[i]) } }
  • 20. 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: %vn", i, s[i]) } }
  • 21. 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: %vn", i, s[i]) } }
  • 22. 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: %vn", i, s[i]) } }
  • 23. 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: %vn", i, s[i]) } }
  • 24. 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: %vn", i, s[i]) } }
  • 26. AN EXCEPTIONAL LOOP package main import . "fmt" func main() { defer func() { recover() }() s := []int{0, 2, 4, 6, 8} i := 0 for { Printf("%v: %vn", i, s[i]) i++ } }
  • 27. AN EXCEPTIONAL LOOP package main import . "fmt" func main() { defer func() { recover() }() s := []int{0, 2, 4, 6, 8} i := 0 for { Printf("%v: %vn", i, s[i]) i++ } }
  • 28. AN EXCEPTIONAL LOOP package main import . "fmt" func main() { defer func() { recover() }() s := []int{0, 2, 4, 6, 8} i := 0 for { Printf("%v: %vn", i, s[i]) i++ } }
  • 29. AN EXCEPTIONAL LOOP package main import . "fmt" func main() { defer func() { recover() }() s := []int{0, 2, 4, 6, 8} i := 0 for { Printf("%v: %vn", i, s[i]) i++ } }
  • 30. AN EXCEPTIONAL LOOP package main import . "fmt" func main() { defer func() { recover() }() s := []int{0, 2, 4, 6, 8} i := 0 for { Printf("%v: %vn", i, s[i]) i++ } }
  • 31. AN EXCEPTIONAL LOOP package main import . "fmt" func main() { defer func() { recover() }() s := []int{0, 2, 4, 6, 8} i := 0 for { Printf("%v: %vn", i, s[i]) i++ } }
  • 32. AN EXCEPTIONAL LOOP package main import . "fmt" func main() { defer func() { recover() }() s := []int{0, 2, 4, 6, 8} i := 0 for i := 0; ; i++ { Printf("%v: %vn", i, s[i]) i++ } }
  • 34. ENUMERABLE RANGES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} for i, v := range s { Printf("%v: %vn", i, v) } }
  • 35. ENUMERABLE RANGES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} for i, v := range s { Printf("%v: %vn", i, v) } }
  • 36. ENUMERABLE RANGES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} for i, v := range s { Printf("%v: %vn", i, v) } }
  • 37. ENUMERABLE RANGES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} for i, v := range s { Printf("%v: %vn", i, v) } }
  • 38. ENUMERABLE RANGES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} for i, v := range s { Printf("%v: %vn", i, v) } }
  • 39. ENUMERABLE RANGES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} for i, v := range s { Printf("%v: %vn", i, v) } }
  • 42. ENUMERATION BY FUNCTION package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s []int) { for i, v := range s { Printf("%v: %vn", i, v) } }
  • 43. ENUMERATION BY FUNCTION package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s []int) { for i, v := range s { Printf("%v: %vn", i, v) } }
  • 44. ENUMERATION BY FUNCTION package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s []int) { for i, v := range s { Printf("%v: %vn", i, v) } }
  • 45. ENUMERATION BY FUNCTION package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s []int) { for i, v := range s { Printf("%v: %vn", i, v) } }
  • 46. ENUMERATION BY FUNCTION package main import . "fmt" func main() { print_slice(0, 2, 4, 6, 8) } func print_slice(s ...int) { for i, v := range s { Printf("%v: %vn", i, v) } }
  • 48. ABSTRACTING TYPE package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s interface{}) { for i, v := range s.([]int) { Printf("%v: %vn", i, v) } }
  • 49. ABSTRACTING TYPE package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s interface{}) { for i, v := range s.([]int) { Printf("%v: %vn", i, v) } }
  • 50. ABSTRACTING TYPE package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s interface{}) { for i, v := range s.([]int) { Printf("%v: %vn", i, v) } }
  • 51. ABSTRACTING TYPE package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s interface{}) { if s, ok := s.([]int); ok { for i, v := range s { Printf("%v: %vn", i, v) } } }
  • 52. ABSTRACTING TYPE package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s interface{}) { if s, ok := s.([]int); ok { for i, v := range s { Printf("%v: %vn", i, v) } } }
  • 53. ABSTRACTING TYPE package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s interface{}) { if s, ok := s.([]int); ok { for i, v := range s { Printf("%v: %vn", i, v) } } }
  • 54. ABSTRACTING TYPE package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s interface{}) { if s, ok := s.([]int); ok { for i, v := range s { Printf("%v: %vn", i, v) } } }
  • 55. ABSTRACTING TYPE package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s interface{}) { switch s := s.(type) { case []int: for i, v := range s { Printf("%v: %vn", i, v) } } }
  • 56. ABSTRACTING TYPE package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s interface{}) { switch s := s.(type) { case []int: for i, v := range s { Printf("%v: %vn", i, v) } } }
  • 57. ABSTRACTING TYPE package main import . "fmt" func main() { print_slice([]int{0, 2, 4, 6, 8}) } func print_slice(s interface{}) { switch s := s.(type) { case []int: for i, v := range s { Printf("%v: %vn", i, v) } } }
  • 59. FUNCTIONS AS VALUES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(s, element) } func element(s []int, i int) int { return s[i] } func print_slice(s []int, f func([]int, int) int { defer func() { recover() }() for i := 0; ; i++ { Printf("%v: %vn", i, f(i)) } }
  • 60. FUNCTIONS AS VALUES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(s, element) } func element(s []int, i int) int { return s[i] } func print_slice(s []int, f func([]int, int) int { defer func() { recover() }() for i := 0; ; i++ { Printf("%v: %vn", i, f(i)) } }
  • 61. FUNCTIONS AS VALUES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(s, element) } func element(s []int, i int) int { return s[i] } func print_slice(s []int, f func([]int, int) int) { defer func() { recover() }() for i := 0; ; i++ { Printf("%v: %vn", i, f(s, i)) } }
  • 62. FUNCTIONS AS VALUES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(s, element) } func element(s []int, i int) int { return s[i] } func print_slice(s []int, f func([]int, int) int) { defer func() { recover() }() for i := 0; ; i++ { Printf("%v: %vn", i, f(s, i)) } }
  • 63. FUNCTIONS AS VALUES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(s, element) } func element(s []int, i int) int { return s[i] } func print_slice(s []int, f func([]int, int) int) { defer func() { recover() }() for i := 0; ; i++ { Printf("%v: %vn", i, f(s, i)) } }
  • 64. FUNCTIONS AS VALUES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(s, element) } func element(s []int, i int) int { return s[i] } func print_slice(s []int, f func([]int, int) int) { defer func() { recover() }() for i := 0; ; i++ { Printf("%v: %vn", i, f(s, i)) } }
  • 65. FUNCTIONS AS VALUES 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] }) } func print_slice(s []int, f func([]int, int) int) { defer func() { recover() }() for i := 0; ; i++ { Printf("%v: %vn", i, f(s, i)) } }
  • 67. CLOSURES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(func(i int) int { return s[i] }) } func print_slice(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } } }
  • 68. CLOSURES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(func(i int) int { return s[i] }) } func print_slice(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } } }
  • 69. CLOSURES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(func(i int) int { return s[i] }) } func print_slice(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } } }
  • 70. CLOSURES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(func(i int) int { return s[i] }) } func print_slice(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } } }
  • 71. CLOSURES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(func(i int) int { return s[i] }) } func print_slice(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } } }
  • 72. CLOSURES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(func(i int) int { return s[i] }) } func print_slice(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } } }
  • 73. CLOSURES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(func(i int) int { return s[i] }) } func print_slice(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } } }
  • 74. CLOSURES package main import . "fmt" func main() { s := []int{0, 2, 4, 6, 8} print_slice(func(i int) int { return s[i] }) } func print_slice(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } } }
  • 76. 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) } func print_channel(c chan int) (i int) { for v := range c { Printf("%v: %vn", i, v) i++ } return }
  • 77. 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) } func print_channel(c chan int) (i int) { for v := range c { Printf("%v: %vn", i, v) i++ } return }
  • 78. CONCURRENCY 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) } func print_channel(c chan int) (i int) { for v := range c { Printf("%v: %vn", i, v) i++ } return }
  • 79. 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) } func print_channel(c chan int) (i int) { for v := range c { Printf("%v: %vn", i, v) i++ } return }
  • 80. 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) } func print_channel(c chan int) (i int) { for v := range c { Printf("%v: %vn", i, v) i++ } return }
  • 81. 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) } func print_channel(c chan int) (i int) { for v := range c { Printf("%v: %vn", i, v) i++ } return }
  • 82. 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) } func print_channel(c chan int) (i int) { for v := range c { Printf("%v: %vn", i, v) i++ } return }
  • 83. CONCURRENCY 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) } func print_channel(c chan int) (i int) { for v := range c { Printf("%v: %vn", i, v) i++ } return }
  • 84. CONCURRENCY 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) } func print_channel(c chan int) (i int) { for v := range c { Printf("%v: %vn", i, v) i++ } return }
  • 85. CONCURRENCY 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) } func print_channel(c chan int) (i int) { for v := range c { Printf("%v: %vn", i, v) i++ } return }
  • 86. CONCURRENCY 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) } func print_channel(c chan int) (i int) { for v := range c { Printf("%v: %vn", i, v) i++ } return }
  • 88. INFINITE SEQUENCES package main import . "fmt" func main() { c := make(chan int) go sequence(c) print_channel(c) } func sequence(c chan int) { for i := 0; ; i++ { c <- i * 2 } } func print_channel(c chan int) { for i := 0; i < 5; i++ { Printf("%v: %vn", i, <- c) } return }
  • 89. INFINITE SEQUENCES package main import . "fmt" func main() { c := make(chan int) go sequence(c) print_channel(c) } func sequence(c chan int) { for i := 0; ; i++ { c <- i * 2 } } func print_channel(c chan int) { for i := 0; i < 5; i++ { Printf("%v: %vn", i, <- c) } return }
  • 90. INFINITE SEQUENCES package main import . "fmt" func main() { c := make(chan int) go sequence(c) print_channel(c) } func sequence(c chan int) { for i := 0; ; i++ { c <- i * 2 } } func print_channel(c chan int) { for i := 0; i < 5; i++ { Printf("%v: %vn", i, <- c) } return }
  • 91. INFINITE SEQUENCES package main import . "fmt" func main() { c := make(chan int) go sequence(c) print_channel(c) } func sequence(c chan int) { for i := 0; ; i++ { c <- i * 2 } } func print_channel(c chan int) { for i := 0; i < 5; i++ { Printf("%v: %vn", i, <- c) } return }
  • 92. INFINITE SEQUENCES package main import . "fmt" func main() { c := make(chan int) go sequence(c) print_channel(c) } func sequence(c chan int) { for i := 0; ; i++ { c <- i * 2 } } func print_channel(c chan int) { for i := 0; i < 5; i++ { Printf("%v: %vn", i, <- c) } return }
  • 94. 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] }) } func print_values(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } case []int: for i, v := range s { Printf("%v: %vn", i, v) } } }
  • 95. 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] }) } func print_values(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } case []int: for i, v := range s { Printf("%v: %vn", i, v) } } }
  • 96. 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] }) } func print_values(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } case []int: for i, v := range s { Printf("%v: %vn", i, v) } } }
  • 97. 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] }) } func print_values(s interface{}) { switch s := s.(type) { case func(int) int: for i := 0; i < 5; i++ { Printf("%v: %vn", i, s(i)) } case []int: for i, v := range s { Printf("%v: %vn", i, v) } } }
  • 98. WORKING WITH KINDS 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] }) } func print_values(s interface{}) { switch s := reflect.ValueOf(s); s.Kind() { case reflect.Func: for i := 0; i < 5; i++ { p := []reflect.Value{ reflect.ValueOf(i) } Printf("%v: %vn", i, s.Call(p)[0].Interface()) } case reflect.Slice: for i := 0; i < s.Len(); i++ { Printf("%v: %vn", i, s.Index(i).Interface()) } } }
  • 99. WORKING WITH KINDS 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] }) } func print_values(s interface{}) { switch s := reflect.ValueOf(s); s.Kind() { case reflect.Func: for i := 0; i < 5; i++ { p := []reflect.Value{ reflect.ValueOf(i) } Printf("%v: %vn", i, s.Call(p)[0].Interface()) } case reflect.Slice: for i := 0; i < s.Len(); i++ { Printf("%v: %vn", i, s.Index(i).Interface()) } } }
  • 100. WORKING WITH KINDS 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] }) } func print_values(s interface{}) { switch s := reflect.ValueOf(s); s.Kind() { case reflect.Func: for i := 0; i < 5; i++ { p := []reflect.Value{ reflect.ValueOf(i) } Printf("%v: %vn", i, s.Call(p)[0].Interface()) } case reflect.Slice: for i := 0; i < s.Len(); i++ { Printf("%v: %vn", i, s.Index(i).Interface()) } } }
  • 101. WORKING WITH KINDS 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] }) } func print_values(s interface{}) { switch s := reflect.ValueOf(s); s.Kind() { case reflect.Func: for i := 0; i < 5; i++ { p := []reflect.Value{ reflect.ValueOf(i) } Printf("%v: %vn", i, s.Call(p)[0].Interface()) } case reflect.Slice: for i := 0; i < s.Len(); i++ { Printf("%v: %vn", i, s.Index(i).Interface()) } } }
  • 102. WORKING WITH KINDS 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] }) } func print_values(s interface{}) { switch s := ValueOf(s); s.Kind() { case Func: for i := 0; i < 5; i++ { p := []Value{ ValueOf(i) } Printf("%v: %vn", i, s.Call(p)[0].Interface()) } case Slice: for i := 0; i < s.Len(); i++ { Printf("%v: %vn", i, s.Index(i).Interface()) } } }
  • 103. WORKING WITH KINDS 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] }) } func print_values(s interface{}) { switch s := ValueOf(s); s.Kind() { case Func: for i := 0; i < 5; i++ { p := []Value{ ValueOf(i) } Printf("%v: %vn", i, s.Call(p)[0].Interface()) } case Slice: for i := 0; i < s.Len(); i++ { Printf("%v: %vn", i, s.Index(i).Interface()) } } }
  • 104. WORKING WITH KINDS 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] }) } func print_values(s interface{}) { switch s := ValueOf(s); s.Kind() { case Func: for i := 0; i < 5; i++ { p := []Value{ ValueOf(i) } Printf("%v: %vn", i, s.Call(p)[0].Interface()) } case Slice: for i := 0; i < s.Len(); i++ { Printf("%v: %vn", i, s.Index(i).Interface()) } } }
  • 105. WORKING WITH KINDS 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] }) } func print_values(s interface{}) { defer func() { recover() } switch s := ValueOf(s); s.Kind() { case Func: for i := 0; ; i++ { p := []Value{ ValueOf(i) } Printf("%v: %vn", i, s.Call(p)[0].Interface()) } case Slice: for i := 0; ; i++ { Printf("%v: %vn", i, s.Index(i).Interface()) } } }
  • 106. WORKING WITH KINDS 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] }) } func print_values(s interface{}) { switch s := ValueOf(s); s.Kind() { case Func: for_each(func(i int) { p := []Value{ ValueOf(i) } Printf("%v: %vn", i, s.Call(p)[0].Interface()) }) case Slice: for_each(func(i int) { Printf("%v: %vn", i, s.Index(i).Interface()) }) } } func for_each(f func(int)) (i int) { defer func() { recover() } for ; ; i++ { f(i) } }
  • 107. WORKING WITH KINDS 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] }) } func print_values(s interface{}) { switch s := ValueOf(s); s.Kind() { case Func: p := make([]Value, 1) for_each(func(i int) { p[0] = ValueOf(i) Printf("%v: %vn", i, s.Call(p)[0].Interface()) }) case Slice: for_each(func(i int) { Printf("%v: %vn", i, s.Index(i).Interface()) }) } } func for_each(f func(int)) (i int) { defer func() { recover() } for ; ; i++ { f(i) } }
  • 110. 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: %vn", i, v) i++ }) } type IterableSlice []int func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 111. 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: %vn", i, v) i++ }) } type IterableSlice []int func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 112. 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: %vn", i, v) i++ }) } type IterableSlice []int func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 113. 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: %vn", i, v) i++ }) } type IterableSlice []int func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 114. 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: %vn", i, v) i++ }) } type IterableSlice []int func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 116. 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: %vn", i, v) i++ }) } type Iterable interface { Each(func(interface{})) } type IterableSlice []int func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 117. 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: %vn", i, v) i++ }) } type Iterable interface { Each(func(interface{})) } type IterableSlice []int func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 118. 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: %vn", i, v) i++ }) } type Iterable interface { Each(func(interface{})) } type IterableSlice []int func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 119. INTERFACES = POLYMORPHISM package main import . "fmt" func main() { print_values(IterableLimit(5)) print_values(IterableSlice{ 0, 2, 4, 6, 8 }) } func print_values(s Iterable) (i int) { s.Each(func(v interface{}) { Printf("%v: %vn", i, v) i++ }) return i } type Iterable interface { Each(func(interface{})) } type IterableLimit int type IterableSlice []int func (i IterableLimit) Each(f func(interface{})) { for v := IterableLimit(0); v < i; v++ { f(v) } } func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 120. INTERFACES = POLYMORPHISM package main import . "fmt" func main() { print_values(IterableLimit(5)) print_values(IterableSlice{ 0, 2, 4, 6, 8 }) } func print_values(s Iterable) (i int) { s.Each(func(v interface{}) { Printf("%v: %vn", i, v) i++ }) return i } type Iterable interface { Each(func(interface{})) } type IterableLimit int type IterableSlice []int func (i IterableLimit) Each(f func(interface{})) { for v := IterableLimit(0); v < i; v++ { f(v) } } func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 121. INTERFACES = POLYMORPHISM package main import . "fmt" func main() { print_values(IterableLimit(5)) print_values(IterableSlice{ 0, 2, 4, 6, 8 }) } func print_values(s Iterable) (i int) { s.Each(func(v interface{}) { Printf("%v: %vn", i, v) i++ }) return i } type Iterable interface { Each(func(interface{})) } type IterableLimit int type IterableSlice []int func (i IterableLimit) Each(f func(interface{})) { for v := IterableLimit(0); v < i; v++ { f(v) } } func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 122. INTERFACES = POLYMORPHISM package main import . "fmt" func main() { print_values(IterableLimit(5)) print_values(IterableSlice{ 0, 2, 4, 6, 8 }) } func print_values(s Iterable) (i int) { s.Each(func(v interface{}) { Printf("%v: %vn", i, v) i++ }) return i } type Iterable interface { Each(func(interface{})) } type IterableLimit int type IterableSlice []int func (i IterableLimit) Each(f func(interface{})) { for v := IterableLimit(0); v < i; v++ { f(v) } } func (i IterableSlice) Each(f func(interface{})) { for _, v := range i { f(v) } }
  • 124. IMMUTABILITY IS A CHOICE package main import . "fmt" func main() { s := IterableRange{ 0, 2, 5 } print_values(s) print_values(s) } func print_values(s Iterable) (i int) { s.Each(func(v interface{}) { Printf("%v: %vn", i, v) i++ }) return i } type Iterable interface { Each(func(interface{})) } type IterableRange struct { start int step int limit int } func (r IterableRange) Each(f func(interface{})) { for; r.limit > 0; r.limit-- { f(r.start) r.start += r.step } }
  • 125. IMMUTABILITY IS A CHOICE package main import . "fmt" func main() { s := IterableRange{ 0, 2, 5 } print_values(s) print_values(s) } func print_values(s Iterable) (i int) { s.Each(func(v interface{}) { Printf("%v: %vn", i, v) i++ }) return i } type Iterable interface { Each(func(interface{})) } type IterableRange struct { start int step int limit int } func (r IterableRange) Each(f func(interface{})) { for; r.limit > 0; r.limit-- { f(r.start) r.start += r.step } }
  • 126. IMMUTABILITY IS A CHOICE package main import . "fmt" func main() { s := IterableRange{ 0, 2, 5 } print_values(s) print_values(s) } func print_values(s Iterable) (i int) { s.Each(func(v interface{}) { Printf("%v: %vn", i, v) i++ }) return i } type Iterable interface { Each(func(interface{})) } type IterableRange struct { start int step int limit int } func (r IterableRange) Each(f func(interface{})) { for; r.limit > 0; r.limit-- { f(r.start) r.start += r.step } }
  • 127. IMMUTABILITY IS A CHOICE package main import . "fmt" func main() { s := IterableRange{ 0, 2, 5 } print_values(s) print_values(s) } func print_values(s Iterable) (i int) { s.Each(func(v interface{}) { Printf("%v: %vn", i, v) i++ }) return i } type Iterable interface { Each(func(interface{})) } type IterableRange struct { start int step int limit int } func (r IterableRange) Each(f func(interface{})) { for; r.limit > 0; r.limit-- { f(r.start) r.start += r.step } }
  • 128. IMMUTABILITY IS A CHOICE package main import . "fmt" func main() { s := &IterableRange{ 0, 2, 5 } print_values(s) print_values(s) } func print_values(s Iterable) (i int) { s.Each(func(v interface{}) { Printf("%v: %vn", i, v) i++ }) return i } type Iterable interface { Each(func(interface{})) } type IterableRange struct { start int step int limit int } func (r IterableRange) Each(f func(interface{})) { for; r.limit > 0; r.limit-- { f(r.start) r.start += r.step } }
  • 129. IMMUTABILITY IS A CHOICE package main import . "fmt" func main() { s := &IterableRange{ 0, 2, 5 } print_values(s) print_values(s) } func print_values(s Iterable) (i int) { s.Each(func(v interface{}) { Printf("%v: %vn", i, v) i++ }) return i } type Iterable interface { Each(func(interface{})) } type IterableRange struct { start int step int limit int } func (r *IterableRange) Each(f func(interface{})) { for; r.limit > 0; r.limit-- { f(r.start) r.start += r.step } }
  • 130. OO makes code understandable by encapsulating moving parts. FP makes code understandable by minimizing moving parts. Michael Feathers @mfeathers LEANPUB://GONOTEBOOK
  • 133. A PURE FUNCTION package main import "os" func main() { os.Exit(add(3, 4)) } func add(x, y int) int { return x + y }
  • 134. A PURE FUNCTION package main import "os" func main() { os.Exit(add(3, 4)) } func add(x, y int) int { return x + y }
  • 135. A PURE FUNCTION package main import "os" func main() { os.Exit(add(3, 4)) } func add(x int, y int) int { return x + y }
  • 136. A PURE FUNCTION package main import "os" func main() { os.Exit(add(3, 4)) } func add(x int, y int) int { return x + y }
  • 137. A PURE FUNCTION package main import "os" func main() { os.Exit(add(3, 4)) } func add(x int, y int) int { return x + y }
  • 138. 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 }
  • 139. 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 }
  • 140. 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 }
  • 141. 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 }
  • 142. 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 }
  • 143. 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 }
  • 145. 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 }
  • 146. 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 }
  • 147. 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 }
  • 148. 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 }
  • 149. 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) }
  • 150. 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) }
  • 151. 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) }
  • 152. 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) }
  • 154. 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() func MakeAccumulator() func(int) int { var y int return func(x int) int { y += x return y } }
  • 155. 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() func MakeAccumulator() func(int) int { var y int return func(x int) int { y += x return y } }
  • 156. 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() func MakeAccumulator() func(int) int { var y int return func(x int) int { y += x return y } }
  • 157. 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() func MakeAccumulator() func(int) int { var y int return func(x int) int { y += x return y } }
  • 158. 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() func MakeAccumulator() func(int) int { var y int return func(x int) int { y += x return y } }
  • 159. 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() type Accumulator func(int) int func MakeAccumulator() Accumulator { var y int return func(x int) int { y += x return y } }
  • 160. 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 } }
  • 161. 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 } }
  • 163. 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) }
  • 164. 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) }
  • 165. 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()) } }
  • 166. 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()) } }
  • 167. 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()) } }
  • 170. COMPUTING FACTORIALS 0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880
  • 172. 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 }
  • 173. 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 }
  • 174. 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 }
  • 175. 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 }
  • 176. 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 }
  • 177. 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 }
  • 178. 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 }
  • 179. 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 }
  • 180. 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 }
  • 182. 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!: %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 }
  • 183. 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!: %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 }
  • 184. 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!: %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 }
  • 185. 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!: %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 }
  • 186. 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!: %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 }
  • 187. 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!: %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 }
  • 188. MULTIPLE FACTORIALS 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 }
  • 190. 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 }
  • 191. 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 }
  • 192. 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 }
  • 193. 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 }
  • 194. 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 }
  • 195. 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 }
  • 196. 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 }
  • 197. 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 }
  • 198. 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) s} }() 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 }
  • 199. 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 }
  • 200. 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 }
  • 201. 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 }
  • 202. 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 }
  • 203. 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 }
  • 206. 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 }
  • 207. 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 }
  • 208. 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 }
  • 209. 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 }
  • 210. 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 }
  • 211. 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 }
  • 212. 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 }
  • 213. 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 }
  • 214. 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 }
  • 215. 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 }
  • 220. RECURSION package main func main() { defer func() { recover() } main() }
  • 221. 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() } }
  • 222. 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() } }
  • 223. 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() } }
  • 224. 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() } }
  • 230. 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 }
  • 231. 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 }
  • 232. 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 }
  • 233. 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 }
  • 234. 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 }
  • 235. 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 }
  • 236. 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 }
  • 237. 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 }
  • 238. 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 }
  • 239. 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 }
  • 240. 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 }
  • 241. 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 }
  • 242. 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 }
  • 244. 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 }
  • 245. 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 }
  • 246. 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 }
  • 247. 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 }
  • 248. 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 }
  • 249. 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 }
  • 250. 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 }
  • 251. 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 } }
  • 252. 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 } }
  • 253. 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 } }
  • 254. 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 } }