SlideShare una empresa de Scribd logo
1 de 46
Descargar para leer sin conexión
Powerful - Flexible - Elegant
Fun with Functions
Solution Engineer @ Loodse
Frank Müller
@themue @themue
With and Without Names
Simple Functions
Simple functions are well known
func Status() int {
return status
}
func SetStatus(s int) {
status = s
}
Arguments and return values are flexible
func HasManyArgs(a int, b, c string, foos ...Foo) {
...
}
func ReturnsMultipleValues() (int, error) {
...
return 12345, nil
}
Calling them is simple
HasManyArgs(12345,”foo”, “bar”, aFoo, anotherFoo)
var i int
var err error
i, err = ReturnsMultipleValues()
Functions don’t always need a name
myNewSlice := All(myOldSlice, func(in string) string {
return strings.ToUpper(in)
})
hits := Find(myNewSlice, func(in string) bool {
l := len(in)
return l >= 3 && l <= 10
})
Their creation context will be captured
func mkMultiAdder(a, b int) func(int) int {
m := a * b
// Closure.
return func(i int) int {
return m + i
}
}
centuryAdder := mkMultiAdder(2, 1000)
thisYear := centuryAdder(20) // 2020
func TestFoo(t *testing.T) {
check := func(ok bool, msg string) {
if !ok {
t.Fatal(msg)
}
}
...
check(a == b, “a should be equal to b”)
check(a%2 == 0, “a should be even”)
}
They can help inside of functions
f, err := os.Open(“file.txt”)
if err != nil {
...
}
defer f.Close()
...
Function calls can be deferred and called on leaving
f, err := os.Open(“file.txt”)
if err != nil {
...
}
defer log.Printf(“closed file: %v”, f.Close()) // !!!
...
But take care, only outer call is deferred
// Fire and forget.
go doSomethingOnce(data)
// Processing in background.
go doSomethingForAll(inC, outC)
// Run until cancelled.
go doForever(ctx)
Goroutines are only functions too
Fixed and Optional
Typical Functions
func All(
ins []string,
process func(string) string) []string {
outs := make([]string, len(ins))
for i, in := range ins {
outs[i] = process(in)
}
return outs
}
Function types may be implicit
type Filter func(string) bool
func Find(ins []string, matches Filter) []string {
var outs []string
for _, in := range ins {
if matches(in) {
outs = append(outs, in)
}
}
return outs
}
But also may have a named type
These named types can be options too
● Think of a complex type with a number of fields
● Concurrent types providing internal services
● Database clients
● Network servers
● ...
● These fields shall have default values
● These fields also shall be optionally configurable
● Functions may help in an elegant way
type Client struct {
address string
timeout time.Duration
poolsize int
logging bool
Initializer func(conn *Connection) error
...
}
type Option func(c *Client) error
How does this Option() help?
func NewClient(options ...Option) (*Client, error) {
c := &Client{ ... }
for _, option := range options {
if err := option(c); err != nil {
return nil, err
}
}
...
return c
}
Construct the Client with options
func WithTimeout(timeout time.Duration) Option {
return func(c *Client) error {
if timeout < minTimeout {
return ErrTimeoutTooLow
}
c.timeout = timeout
return nil
}
}
Options with arguments and validation
client, err := database.NewClient(
database.WithAddress(“db.mycompany.com:6379”),
database.WithPoolsize(16),
database.WithoutLogging(),
database.WithInitializer(
func(conn *database.Connection) error {
...
}),
)
All together from user perspective
With and Without Interfaces
Methodological Functions
type Counter struct {
value int
}
func (c *Counter) Incr() {
c.value++
}
func (c Counter) Get() int {
return c.value
}
Methods are simply functions with a receiver
type Adder struct {
base int
}
func NewAdder(base int) Adder {
return Adder{base}
}
func (a Adder) Add(i int) int {
return a.base + i
}
Really? Yes, be patient
adder := NewAdder(2000)
add := adder.Add
thisYear := add(20) // 2020
And where is the function?
type IntGetter interface {
Get() int
}
func (c Counter) Get() int {
return c.value
}
func (a Age) Get() int {
return int(time.Now().Sub(a.birthday) / 24)
}
Method sets aka interfaces are flexible
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(
w ResponseWriter, r *Request) {
f(w, r)
}
Can function types implement interfaces too? Sure!
Let’s replace the Logic
Handle Events
type Event struct {
...
}
type Handler func(evt Event) (Handler, error)
type Machine struct {
handle Handler
}
There events, handlers, and machines
func (m *Machine) Next(evt Event) error {
handler, err := m.handle(evt)
if err != nil {
return err
}
m.handle = handler
}
Let the events flow
func home(evt Event) (Handler, error) {
switch evt.Kind {
case takeTrain:
return work, nil
case sleep:
return bed, nil
default:
return nil, errors.New(“illegal event”)
}
}
Example: Game of Life (1/3)
func work(evt Event) (Handler, error) {
switch evt.Kind {
case takeTrain:
return home, nil
default:
return nil, errors.New(“illegal event”)
}
}
Example: Game of Life (2/3)
func bed(evt Event) (Handler, error) {
switch evt.Kind {
case takeTrain:
return wake, nil
default:
return nil, errors.New(“illegal event”)
}
}
Example: Game of Life (3/3)
● For real scenarios work with structs and methods
● Struct contains the additional data the states can act on
● Individual methods with the same signature represent the handlers
● func (m *Machine) home(evt Event) (Handler, error)
● func (m *Machine) work(evt Event) (Handler, error)
● func (m *Machine) bed(evt Event) (Handler, error)
● func (m *Machine) sports(evt Event) (Handler, error)
● ...
Trivial example
Sequential Processing
Traveling Functions
func (mt *myType) backend() {
for {
select {
case one := <-mt.oneC:
...
case two := <-mt.twoC:
...
}
}
}
You know this pattern
Handle concurrency with care
● Concurrency is a powerful mechanism
● Unsynchronized access to data quickly leads to troubles
● Go provides goroutines for work and channels for communication
● Static typing needs individual channels for individual types
● So overhead of goroutine loop and helper types to transport reply channels
grows
● Functions as types may help here too
type ProcessFunc func(string) string
type Processor struct {
ctx context.Context
process ProcessFunc
buffer []string
actions chan func()
}
Think of a synchronized buffered text processor
func New(ctx context.Context, pf ProcessFunc) *Processor {
p := &Processor{
ctx: ctx,
process: pf,
actions: make(chan func(), queueSize),
}
go p.backend()
return p
}
Constructing is simple
func (p *Processor) backend() {
for {
select {
case <-p.ctx.Done():
return
case action := <-p.actions:
action()
}
}
}
Actions are performed in backend method
func (p *Processor) Push(lines ...string) {
p.actions <- func() {
for _, line := range lines {
p.buffer = append(p.buffer, p.process(line))
}
}
}
Logic is defined in public methods
func (p *Processor) Pull() (string, error) {
var line string
var err error
done := make(chan struct{})
p.actions <- func() {
defer close(done)
if len(p.buffer) == 0 {
err = errors.New(“empty buffer”)
return
}
...
Return values are possible too (1/2)
...
line = p.buffer[0]
p.buffer = p.buffer[1:]
}
<-done
return line, err
}
Return values are possible too (2/2)
● Extra unbuffered action channel for synchronous methods
● Private methods for runtime logic
● Taking care if the backend goroutine still runs
● Method doSync(action func()) error for synchronous actions
● Method doAsync(action func()) error for asynchronous actions
● Stop() error method to close the context by wrapping it with
context.WithCancel()
● Err() error method to return internal status
Extensions help
Powerful - Flexible - Elegant
Summary
● Very simple to understand
● Powerful variants
● Flexibly usable by composition
● Closures are an elegant way to encapsulate logic with access to their
context
● Methods are functions knowing the instance they are defined for
● Functions via channels help to keep concurrency maintainable
Functions are primary ingredients of the language
Questions?

Más contenido relacionado

La actualidad más candente

F# Presentation
F# PresentationF# Presentation
F# Presentation
mrkurt
 
C interview question answer 2
C interview question answer 2C interview question answer 2
C interview question answer 2
Amit Kapoor
 

La actualidad más candente (20)

Python for data science by www.dmdiploma.com
Python for data science by www.dmdiploma.comPython for data science by www.dmdiploma.com
Python for data science by www.dmdiploma.com
 
F# Presentation
F# PresentationF# Presentation
F# Presentation
 
Learn c++ (functions) with nauman ur rehman
Learn  c++ (functions) with nauman ur rehmanLearn  c++ (functions) with nauman ur rehman
Learn c++ (functions) with nauman ur rehman
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
Python programming
Python  programmingPython  programming
Python programming
 
Python unit 3 and Unit 4
Python unit 3 and Unit 4Python unit 3 and Unit 4
Python unit 3 and Unit 4
 
Kotlin
KotlinKotlin
Kotlin
 
C++ references
C++ referencesC++ references
C++ references
 
C interview question answer 2
C interview question answer 2C interview question answer 2
C interview question answer 2
 
C++11
C++11C++11
C++11
 
Recursion to iteration automation.
Recursion to iteration automation.Recursion to iteration automation.
Recursion to iteration automation.
 
Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)
 
Golang and Eco-System Introduction / Overview
Golang and Eco-System Introduction / OverviewGolang and Eco-System Introduction / Overview
Golang and Eco-System Introduction / Overview
 
Lecture#8 introduction to array with examples c++
Lecture#8 introduction to array with examples c++Lecture#8 introduction to array with examples c++
Lecture#8 introduction to array with examples c++
 
Fp201 unit5 1
Fp201 unit5 1Fp201 unit5 1
Fp201 unit5 1
 
Beginning Python
Beginning PythonBeginning Python
Beginning Python
 
Maharishi University of Management (MSc Computer Science test questions)
Maharishi University of Management (MSc Computer Science test questions)Maharishi University of Management (MSc Computer Science test questions)
Maharishi University of Management (MSc Computer Science test questions)
 
Functional programming
Functional programmingFunctional programming
Functional programming
 
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
 
Composition birds-and-recursion
Composition birds-and-recursionComposition birds-and-recursion
Composition birds-and-recursion
 

Similar a Fun with functions

TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class Functions
Eelco Visser
 
Dti2143 chapter 5
Dti2143 chapter 5Dti2143 chapter 5
Dti2143 chapter 5
alish sha
 
2.2 higher order-functions
2.2 higher order-functions2.2 higher order-functions
2.2 higher order-functions
futurespective
 

Similar a Fun with functions (20)

Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
ProgrammingwithGOLang
ProgrammingwithGOLangProgrammingwithGOLang
ProgrammingwithGOLang
 
Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my day
 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class Functions
 
Dti2143 chapter 5
Dti2143 chapter 5Dti2143 chapter 5
Dti2143 chapter 5
 
An introduction to functional programming with Swift
An introduction to functional programming with SwiftAn introduction to functional programming with Swift
An introduction to functional programming with Swift
 
golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptx
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 
Introduction to go
Introduction to goIntroduction to go
Introduction to go
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of Go
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
Go Lang Tutorial
Go Lang TutorialGo Lang Tutorial
Go Lang Tutorial
 
2.2 higher order-functions
2.2 higher order-functions2.2 higher order-functions
2.2 higher order-functions
 
10. funtions and closures IN SWIFT PROGRAMMING
10. funtions and closures IN SWIFT PROGRAMMING10. funtions and closures IN SWIFT PROGRAMMING
10. funtions and closures IN SWIFT PROGRAMMING
 
functions
functionsfunctions
functions
 
Functions - complex first class citizen
Functions - complex first class citizenFunctions - complex first class citizen
Functions - complex first class citizen
 
Monads in Swift
Monads in SwiftMonads in Swift
Monads in Swift
 
Developer Experience i TypeScript. Najbardziej ikoniczne duo
Developer Experience i TypeScript. Najbardziej ikoniczne duoDeveloper Experience i TypeScript. Najbardziej ikoniczne duo
Developer Experience i TypeScript. Najbardziej ikoniczne duo
 

Más de Frank Müller

RESTful Web Applications with Google Go
RESTful Web Applications with Google GoRESTful Web Applications with Google Go
RESTful Web Applications with Google Go
Frank Müller
 
Pecha Kucha: Nebenläufigkeit als natürliches Paradigma
Pecha Kucha: Nebenläufigkeit als natürliches ParadigmaPecha Kucha: Nebenläufigkeit als natürliches Paradigma
Pecha Kucha: Nebenläufigkeit als natürliches Paradigma
Frank Müller
 

Más de Frank Müller (20)

JAX 2023 - Cloud Provider APIs
JAX 2023 - Cloud Provider APIsJAX 2023 - Cloud Provider APIs
JAX 2023 - Cloud Provider APIs
 
JAX 2023 - Generics in Go
JAX 2023 - Generics in GoJAX 2023 - Generics in Go
JAX 2023 - Generics in Go
 
Let The Computer Do It
Let The Computer Do ItLet The Computer Do It
Let The Computer Do It
 
Concurrency with Go
Concurrency with GoConcurrency with Go
Concurrency with Go
 
2021 OOP - Kubernetes Operatoren
2021   OOP - Kubernetes Operatoren2021   OOP - Kubernetes Operatoren
2021 OOP - Kubernetes Operatoren
 
DevOpsCon - Verteilte Entwicklung in Go
DevOpsCon - Verteilte Entwicklung in GoDevOpsCon - Verteilte Entwicklung in Go
DevOpsCon - Verteilte Entwicklung in Go
 
Devs@Home - Einführung in Go
Devs@Home - Einführung in GoDevs@Home - Einführung in Go
Devs@Home - Einführung in Go
 
Ein Gopher im Netz
Ein Gopher im NetzEin Gopher im Netz
Ein Gopher im Netz
 
Blockchains - Mehr als nur digitale Währungen
Blockchains - Mehr als nur digitale WährungenBlockchains - Mehr als nur digitale Währungen
Blockchains - Mehr als nur digitale Währungen
 
Spaß an der Nebenläufigkeit
Spaß an der NebenläufigkeitSpaß an der Nebenläufigkeit
Spaß an der Nebenläufigkeit
 
Go - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeGo - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare Systeme
 
Cloud Provisioning mit Juju
Cloud Provisioning mit JujuCloud Provisioning mit Juju
Cloud Provisioning mit Juju
 
Juju - Scalable Software with Google Go
Juju - Scalable Software with Google GoJuju - Scalable Software with Google Go
Juju - Scalable Software with Google Go
 
RESTful Web Applications with Google Go
RESTful Web Applications with Google GoRESTful Web Applications with Google Go
RESTful Web Applications with Google Go
 
Clouds, leicht beherrschbar
Clouds, leicht beherrschbarClouds, leicht beherrschbar
Clouds, leicht beherrschbar
 
Skalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google GoSkalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google Go
 
WTC 2013 - Juju - Mit etwas Magie zur perfekten Cloud
WTC 2013 - Juju - Mit etwas Magie zur perfekten CloudWTC 2013 - Juju - Mit etwas Magie zur perfekten Cloud
WTC 2013 - Juju - Mit etwas Magie zur perfekten Cloud
 
Juju - Google Go in a scalable Environment
Juju - Google Go in a scalable EnvironmentJuju - Google Go in a scalable Environment
Juju - Google Go in a scalable Environment
 
OOP 2013 - Weltweite Entwicklung von Open Source Software
OOP 2013 - Weltweite Entwicklung von Open Source SoftwareOOP 2013 - Weltweite Entwicklung von Open Source Software
OOP 2013 - Weltweite Entwicklung von Open Source Software
 
Pecha Kucha: Nebenläufigkeit als natürliches Paradigma
Pecha Kucha: Nebenläufigkeit als natürliches ParadigmaPecha Kucha: Nebenläufigkeit als natürliches Paradigma
Pecha Kucha: Nebenläufigkeit als natürliches Paradigma
 

Último

%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 

Último (20)

WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
WSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - Kanchana
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 

Fun with functions

  • 1. Powerful - Flexible - Elegant Fun with Functions
  • 2. Solution Engineer @ Loodse Frank Müller @themue @themue
  • 3. With and Without Names Simple Functions
  • 4. Simple functions are well known func Status() int { return status } func SetStatus(s int) { status = s }
  • 5. Arguments and return values are flexible func HasManyArgs(a int, b, c string, foos ...Foo) { ... } func ReturnsMultipleValues() (int, error) { ... return 12345, nil }
  • 6. Calling them is simple HasManyArgs(12345,”foo”, “bar”, aFoo, anotherFoo) var i int var err error i, err = ReturnsMultipleValues()
  • 7. Functions don’t always need a name myNewSlice := All(myOldSlice, func(in string) string { return strings.ToUpper(in) }) hits := Find(myNewSlice, func(in string) bool { l := len(in) return l >= 3 && l <= 10 })
  • 8. Their creation context will be captured func mkMultiAdder(a, b int) func(int) int { m := a * b // Closure. return func(i int) int { return m + i } } centuryAdder := mkMultiAdder(2, 1000) thisYear := centuryAdder(20) // 2020
  • 9. func TestFoo(t *testing.T) { check := func(ok bool, msg string) { if !ok { t.Fatal(msg) } } ... check(a == b, “a should be equal to b”) check(a%2 == 0, “a should be even”) } They can help inside of functions
  • 10. f, err := os.Open(“file.txt”) if err != nil { ... } defer f.Close() ... Function calls can be deferred and called on leaving
  • 11. f, err := os.Open(“file.txt”) if err != nil { ... } defer log.Printf(“closed file: %v”, f.Close()) // !!! ... But take care, only outer call is deferred
  • 12. // Fire and forget. go doSomethingOnce(data) // Processing in background. go doSomethingForAll(inC, outC) // Run until cancelled. go doForever(ctx) Goroutines are only functions too
  • 14. func All( ins []string, process func(string) string) []string { outs := make([]string, len(ins)) for i, in := range ins { outs[i] = process(in) } return outs } Function types may be implicit
  • 15. type Filter func(string) bool func Find(ins []string, matches Filter) []string { var outs []string for _, in := range ins { if matches(in) { outs = append(outs, in) } } return outs } But also may have a named type
  • 16. These named types can be options too ● Think of a complex type with a number of fields ● Concurrent types providing internal services ● Database clients ● Network servers ● ... ● These fields shall have default values ● These fields also shall be optionally configurable ● Functions may help in an elegant way
  • 17. type Client struct { address string timeout time.Duration poolsize int logging bool Initializer func(conn *Connection) error ... } type Option func(c *Client) error How does this Option() help?
  • 18. func NewClient(options ...Option) (*Client, error) { c := &Client{ ... } for _, option := range options { if err := option(c); err != nil { return nil, err } } ... return c } Construct the Client with options
  • 19. func WithTimeout(timeout time.Duration) Option { return func(c *Client) error { if timeout < minTimeout { return ErrTimeoutTooLow } c.timeout = timeout return nil } } Options with arguments and validation
  • 20. client, err := database.NewClient( database.WithAddress(“db.mycompany.com:6379”), database.WithPoolsize(16), database.WithoutLogging(), database.WithInitializer( func(conn *database.Connection) error { ... }), ) All together from user perspective
  • 21. With and Without Interfaces Methodological Functions
  • 22. type Counter struct { value int } func (c *Counter) Incr() { c.value++ } func (c Counter) Get() int { return c.value } Methods are simply functions with a receiver
  • 23. type Adder struct { base int } func NewAdder(base int) Adder { return Adder{base} } func (a Adder) Add(i int) int { return a.base + i } Really? Yes, be patient
  • 24. adder := NewAdder(2000) add := adder.Add thisYear := add(20) // 2020 And where is the function?
  • 25. type IntGetter interface { Get() int } func (c Counter) Get() int { return c.value } func (a Age) Get() int { return int(time.Now().Sub(a.birthday) / 24) } Method sets aka interfaces are flexible
  • 26. type Handler interface { ServeHTTP(ResponseWriter, *Request) } type HandlerFunc func(ResponseWriter, *Request) func (f HandlerFunc) ServeHTTP( w ResponseWriter, r *Request) { f(w, r) } Can function types implement interfaces too? Sure!
  • 27. Let’s replace the Logic Handle Events
  • 28. type Event struct { ... } type Handler func(evt Event) (Handler, error) type Machine struct { handle Handler } There events, handlers, and machines
  • 29. func (m *Machine) Next(evt Event) error { handler, err := m.handle(evt) if err != nil { return err } m.handle = handler } Let the events flow
  • 30. func home(evt Event) (Handler, error) { switch evt.Kind { case takeTrain: return work, nil case sleep: return bed, nil default: return nil, errors.New(“illegal event”) } } Example: Game of Life (1/3)
  • 31. func work(evt Event) (Handler, error) { switch evt.Kind { case takeTrain: return home, nil default: return nil, errors.New(“illegal event”) } } Example: Game of Life (2/3)
  • 32. func bed(evt Event) (Handler, error) { switch evt.Kind { case takeTrain: return wake, nil default: return nil, errors.New(“illegal event”) } } Example: Game of Life (3/3)
  • 33. ● For real scenarios work with structs and methods ● Struct contains the additional data the states can act on ● Individual methods with the same signature represent the handlers ● func (m *Machine) home(evt Event) (Handler, error) ● func (m *Machine) work(evt Event) (Handler, error) ● func (m *Machine) bed(evt Event) (Handler, error) ● func (m *Machine) sports(evt Event) (Handler, error) ● ... Trivial example
  • 35. func (mt *myType) backend() { for { select { case one := <-mt.oneC: ... case two := <-mt.twoC: ... } } } You know this pattern
  • 36. Handle concurrency with care ● Concurrency is a powerful mechanism ● Unsynchronized access to data quickly leads to troubles ● Go provides goroutines for work and channels for communication ● Static typing needs individual channels for individual types ● So overhead of goroutine loop and helper types to transport reply channels grows ● Functions as types may help here too
  • 37. type ProcessFunc func(string) string type Processor struct { ctx context.Context process ProcessFunc buffer []string actions chan func() } Think of a synchronized buffered text processor
  • 38. func New(ctx context.Context, pf ProcessFunc) *Processor { p := &Processor{ ctx: ctx, process: pf, actions: make(chan func(), queueSize), } go p.backend() return p } Constructing is simple
  • 39. func (p *Processor) backend() { for { select { case <-p.ctx.Done(): return case action := <-p.actions: action() } } } Actions are performed in backend method
  • 40. func (p *Processor) Push(lines ...string) { p.actions <- func() { for _, line := range lines { p.buffer = append(p.buffer, p.process(line)) } } } Logic is defined in public methods
  • 41. func (p *Processor) Pull() (string, error) { var line string var err error done := make(chan struct{}) p.actions <- func() { defer close(done) if len(p.buffer) == 0 { err = errors.New(“empty buffer”) return } ... Return values are possible too (1/2)
  • 42. ... line = p.buffer[0] p.buffer = p.buffer[1:] } <-done return line, err } Return values are possible too (2/2)
  • 43. ● Extra unbuffered action channel for synchronous methods ● Private methods for runtime logic ● Taking care if the backend goroutine still runs ● Method doSync(action func()) error for synchronous actions ● Method doAsync(action func()) error for asynchronous actions ● Stop() error method to close the context by wrapping it with context.WithCancel() ● Err() error method to return internal status Extensions help
  • 44. Powerful - Flexible - Elegant Summary
  • 45. ● Very simple to understand ● Powerful variants ● Flexibly usable by composition ● Closures are an elegant way to encapsulate logic with access to their context ● Methods are functions knowing the instance they are defined for ● Functions via channels help to keep concurrency maintainable Functions are primary ingredients of the language