Introduction to different polymorphism techniques. During the presentation I'm trying to persuade why we need simplicity in IT: both for maintenance and producing high quality software.
My lecture leads to one language which accomplish that art pretty well: Go .
Blog post for this presentation: http://rz.scale-it.pl/2015/01/21/a_simple_way_for_polymorphism_and_structured_programming___go_interfaces.html
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
A simple way for polymorphism and structured programming - Go interfaces
1. A simple way for polymorphism and structured
programming
Polymorphism in Go
Robert Zaremba
AgFlow
Wroclaw 2015-01-08
2. Me
ii
Studied MSc of Computer Science at University of Wroclaw
http://rz.scale-it.pl
Profession
CTO @ AgFlow
Coding professionally in Go, Python, Haskell
Co-organizer of Geneva Haskell Group
Hiring
We are doing a world commodities market analysis. Contact me if
you are looking for an interesting job.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 2 / 29
3. What is a Polymorphism?
OOP
In object-oriented programming, polymorphism refers to a
programming language’s ability to process objects differently
depending on their data type or class.
For example, given a base class shape, polymorphism enables the
programmer to define different area methods for any number of
derived classes, such as circles, rectangles and triangles.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 3 / 29
4. What is a Polymorphism?
Biology
Morph
Greek: form, shape.
Is a visual or behavioural difference between organisms of distinct
populations.
Polymorphism in biology occurs when two or more clearly different
phenotypes exist in the same population of a species.
In order to be classified as such, morphs must occupy the same
habitat at the same time and belong to a panmictic population (all
individuals are potential partners).
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 4 / 29
5. What is a Polymorphism?
Biology
Morph
Greek: form, shape.
Is a visual or behavioural difference between organisms of distinct
populations.
Polymorphism in biology occurs when two or more clearly different
phenotypes exist in the same population of a species.
In order to be classified as such, morphs must occupy the same
habitat at the same time and belong to a panmictic population (all
individuals are potential partners).
Also
Molecular biologists use that term to describe certain point mutations
in the genotype.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 4 / 29
6. What is a Polymorphism?
Computer Science
Algebra revision
A structure-preserving map from one mathematical structure to
another.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 5 / 29
7. What is a Polymorphism?
Computer Science
Algebra revision
A structure-preserving map from one mathematical structure to
another.
Programming Languages and type theory revision
provision of a single interface to entities of different types.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 5 / 29
8. What is a Polymorphism?
Computer Science
Algebra revision
A structure-preserving map from one mathematical structure to
another.
Programming Languages and type theory revision
provision of a single interface to entities of different types.
Key feature:
A value is polymorphic if there is more than one type it
can have.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 5 / 29
9. Polymorphism ≡ multiple types?
What does it mean that value can have more
then one type?
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 6 / 29
10. Polymorphism ≡ multiple types?
Parametric polymorphism
Parametric polymorphism
Type of a value contains one or more (unconstrained) type variables.
id: a -> a
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 7 / 29
11. Polymorphism ≡ multiple types?
Parametric polymorphism
Parametric polymorphism
Type of a value contains one or more (unconstrained) type variables.
id: a -> a
data pair a b = Pair a b
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 7 / 29
12. Polymorphism ≡ multiple types?
Parametric polymorphism
Parametric polymorphism
Type of a value contains one or more (unconstrained) type variables.
id: a -> a
data pair a b = Pair a b
type unification!
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 7 / 29
13. Polymorphism ≡ multiple types?
Ad-hoc polymorphism
Ad-hoc polymorphism
A value is able to adopt any one of several types.
Eg. because it, or a value it uses, has been given a separate definition
for each of those types
function multiple dispatch (C, Julia, . . . )
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 8 / 29
14. Polymorphism ≡ multiple types?
Ad-hoc polymorphism
Ad-hoc polymorphism
A value is able to adopt any one of several types.
Eg. because it, or a value it uses, has been given a separate definition
for each of those types
function multiple dispatch (C, Julia, . . . )
function multiple dispatch build in a language (eg building
operators overloading: +, -, *, ...
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 8 / 29
15. Polymorphism ≡ multiple types?
Ad-hoc polymorphism
Ad-hoc polymorphism
A value is able to adopt any one of several types.
Eg. because it, or a value it uses, has been given a separate definition
for each of those types
function multiple dispatch (C, Julia, . . . )
function multiple dispatch build in a language (eg building
operators overloading: +, -, *, ...
type classes
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 8 / 29
16. Polymorphism ≡ multiple types?
Ad-hoc polymorphism
Ad-hoc polymorphism
A value is able to adopt any one of several types.
Eg. because it, or a value it uses, has been given a separate definition
for each of those types
function multiple dispatch (C, Julia, . . . )
function multiple dispatch build in a language (eg building
operators overloading: +, -, *, ...
type classes
traits
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 8 / 29
17. Polymorphism ≡ multiple types?
Ad-hoc polymorphism
Ad-hoc polymorphism
A value is able to adopt any one of several types.
Eg. because it, or a value it uses, has been given a separate definition
for each of those types
function multiple dispatch (C, Julia, . . . )
function multiple dispatch build in a language (eg building
operators overloading: +, -, *, ...
type classes
traits
lambda calculus with parametric polymorphism
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 8 / 29
18. Polymorphism ≡ multiple types?
Subtyping
Well known inheritance.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 9 / 29
19. Polymorphism ≡ multiple types?
Subtyping
Well known inheritance.
Hate
What was first: a chicken or an egg?
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 9 / 29
20. Polymorphism ≡ multiple types?
Subtyping
Well known inheritance.
Hate
What was first: a chicken or an egg?
class Animal abstract String talk(); abstract
move(int, int)
Only Animals can talk? All animals can talk? What about voice
producing?
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 9 / 29
21. Polymorphism ≡ multiple types?
Subtyping
Well known inheritance.
Hate
What was first: a chicken or an egg?
class Animal abstract String talk(); abstract
move(int, int)
Only Animals can talk? All animals can talk? What about voice
producing?
http://www.scala-lang.org/api/current/#scala.
collection.Map — problem with inheritance hierarchy
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 9 / 29
22. Polymorphism ≡ multiple types?
Subtyping
Well known inheritance.
Hate
What was first: a chicken or an egg?
class Animal abstract String talk(); abstract
move(int, int)
Only Animals can talk? All animals can talk? What about voice
producing?
http://www.scala-lang.org/api/current/#scala.
collection.Map — problem with inheritance hierarchy
trait Map[A, +B] extends Iterable[(A, B)] with
GenMap[A, B] with MapLike[A, B, Map[A, B]]
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 9 / 29
23. Polymorphism ≡ multiple types?
Subtyping
Well known inheritance.
Hate
What was first: a chicken or an egg?
class Animal abstract String talk(); abstract
move(int, int)
Only Animals can talk? All animals can talk? What about voice
producing?
http://www.scala-lang.org/api/current/#scala.
collection.Map — problem with inheritance hierarchy
trait Map[A, +B] extends Iterable[(A, B)] with
GenMap[A, B] with MapLike[A, B, Map[A, B]]
trait Iterable[+A] extends Traversable[A] with
GenIterable[A] with GenericTraversableTemplate[A,
Iterable] with IterableLike[A, Iterable[A]]
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 9 / 29
24. Polymorphism ≡ multiple types?
Subtyping
Well known inheritance.
Hate
What was first: a chicken or an egg?
class Animal abstract String talk(); abstract
move(int, int)
Only Animals can talk? All animals can talk? What about voice
producing?
http://www.scala-lang.org/api/current/#scala.
collection.Map — problem with inheritance hierarchy
trait Map[A, +B] extends Iterable[(A, B)] with
GenMap[A, B] with MapLike[A, B, Map[A, B]]
trait Iterable[+A] extends Traversable[A] with
GenIterable[A] with GenericTraversableTemplate[A,
Iterable] with IterableLike[A, Iterable[A]]
Traversable, GenIterable, . . . “state of the art”? WTF??
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 9 / 29
29. Go programming language
Go is simple
Go is a super simple programming language
C-like
no inheritance
just functions
GC - a lot of heavy work has been done
awesome concurrency
static typed
https://golang.org/ref/spec 75 pages
compare to C++ spec: 1368 pages
zen of Go
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 12 / 29
30. Go programming language
Scope
We will not talk about awesome concurrency
We will talk about dynamic interfaces.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 13 / 29
31. Go Interfaces
What is an interface in Go
Interfaces in Go
A simple, limited form of ad-hoc polymorphism. They provide a way
to specify the behavior of an object: if something can do this, then it
can be used here.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 14 / 29
32. Go Interfaces
What is an interface in Go
Interfaces in Go
A simple, limited form of ad-hoc polymorphism. They provide a way
to specify the behavior of an object: if something can do this, then it
can be used here.
Type overview:
pragmatic type system
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 14 / 29
33. Go Interfaces
What is an interface in Go
Interfaces in Go
A simple, limited form of ad-hoc polymorphism. They provide a way
to specify the behavior of an object: if something can do this, then it
can be used here.
Type overview:
pragmatic type system
trade-off between scope bound OOP and super-hiper-fancy hard
type systems (hard Haskell, wtf Scala, having almost everything
C++).
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 14 / 29
34. Go Interfaces
1 package main
2 import (
3 "fmt"
4 "math"
5 )
6
7 type Vertex struct {
8 X, Y float64
9 }
10
11 func (v *Vertex) Abs() float64 {
12 return math.Sqrt(v.X*v.X + v.Y*v.Y)
13 }
14
15 func main() {
16 v := &Vertex{3, 4}
17 fmt.Println(v.Abs())
18 }
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 15 / 29
35. Go Interfaces
1 type Abser interface {
2 Abs() float64
3 }
4 type MyFloat float64
5 func (f MyFloat) Abs() float64 {
6 if f < 0 {
7 return float64(-f)
8 }
9 return float64(f)
10 }
11 func main() {
12 var a Abser
13 f := MyFloat(-math.Sqrt2)
14 v := Vertex{3, 4}
15 a = f // a MyFloat implements Abser
16 a = &v // a *Vertex implements Abser
17 // In the following line, v is a Vertex (not *Vertex)
18 // and does NOT implement Abser.
19 a = v
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 16 / 29
36. Go Interfaces
Interfaces are implicit
A type implements an interface by implementing the methods. There
is no ”implements” keyword.
Implicit interfaces decouple implementation packages from the
packages that define the interfaces: neither depends on the other.
Unlike Haskell you don’t need to explicitly implement type classes.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 17 / 29
37. Go Interfaces
Minimalism and compose-ability
Like in haskell you are encourage to declare minimum meaningful
interfaces and compose them.
1 type Reader interface {
2 Read(b []byte) (n int, err error)
3 }
4
5 type Writer interface {
6 Write(b []byte) (n int, err error)
7 }
8
9 type ReadWriter interface {
10 Reader
11 Writer
12 }
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 18 / 29
38. Go Interfaces
Alternative implementations
Like in Haskell you need to wrap types if you want to provide more
then one implementation of some interface.
1 type VertexManhattan {
2 Vertex
3 }
4
5 func (v *VertexManhattan) Abs() float64 {
6 return MyFloat(v.X).Abs() + MyFloat(v.Y).Abs()
7 }
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 19 / 29
39. Go Interfaces
Minimalism and API clarity
Ideally all your packages should expose interface values.
All your package functions should take interfaces instead of struct
types.
Interface upgrades
There is a powerful feature - interface updates. From the minimum
implementation you can check more powerful object features by
checking which other interfaces are implemented from a minimum
type.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 20 / 29
40. Go dynamic Interfaces
dynamic type
Go types can be cast to wider or even unrelated interfaces if their
dynamic types support it.
Duck duck typing!
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 21 / 29
41. Go dynamic Interfaces
The io package defines two auxiliary types, io.WriterTo and
io.ReaderFrom which io.Readers and io.Writers (respectively) may
optionally implement.
1 func Copy(dst Writer, src Reader) (written int64, err error) {
2 // If the reader has a WriteTo method, use it to
3 // do the copy. Avoids an allocation and a copy.
4 if wt, ok := src.(WriterTo); ok {
5 return wt.WriteTo(dst)
6 }
7 // Similarly, if the writer has a ReadFrom method,
8 // use it to do the copy.
9 if rt, ok := dst.(ReaderFrom); ok {
10 return rt.ReadFrom(src)
11 }
12 ...
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 22 / 29
42. Go dynamic Interfaces
1 buf := make([]byte, 32*1024)
2 for {
3 nr, er := src.Read(buf)
4 if nr > 0 {
5 nw, ew := dst.Write(buf[0:nr])
6 if nw > 0 {
7 written += int64(nw)
8 }
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 23 / 29
43. Go interfaces trap
1 type StatusLogger struct {
2 http.ResponseWriter
3 StatusCode int
4 }
5
6 func (s *StatusLogger) WriteHeader(code int) {
7 s.StatusCode = code
8 s.ResponseWriter.WriteHeader(code)
9 }
StatusLogger only implements http.ResponseWriter, even so
the underlying object may implement rich functionality.
it doesn’t implement any interface upgrades. Using it you will
not provide all performance characteristics (eg. through
ReaderFrom) even the underlying response writer will provide
them.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 24 / 29
44. Go interfaces trap
1 type StatusLogger struct {
2 http.ResponseWriter
3 StatusCode int
4 }
5
6 func (s *StatusLogger) WriteHeader(code int) {
7 s.StatusCode = code
8 s.ResponseWriter.WriteHeader(code)
9 }
It is impossible to write a general-purpose proxy type.
All proxy interfaces will hide possible interface updates
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 24 / 29
45. Go interfaces trap
1 type StatusLogger struct {
2 http.ResponseWriter
3 StatusCode int
4 }
5
6 func (s *StatusLogger) WriteHeader(code int) {
7 s.StatusCode = code
8 s.ResponseWriter.WriteHeader(code)
9 }
Solution: you will need to manually implement a new structure
which will satisfy a richer interface, as shown in the example below.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 24 / 29
46. Writing a proxy object
Wrapping a ResponseWriter
A Writer wrapper from Goji web framework.
1 // WrapWriter wraps an http.ResponseWriter into a proxy that
2 // allows you to hook into various parts of the response process.
3 func WrapWriter(w http.ResponseWriter) WriterProxy {
4 _, cn := w.(http.CloseNotifier)
5 _, fl := w.(http.Flusher)
6 _, hj := w.(http.Hijacker)
7 _, rf := w.(io.ReaderFrom)
8 bw := basicWriter{ResponseWriter: w}
9 if cn && fl && hj && rf {
10 return &fancyWriter{bw}
11 }
12 return &bw
13 }
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 25 / 29
47. Writing a proxy object
Basic writer in action
1 func (b *basicWriter) Write(buf []byte) (int, error) {
2 b.WriteHeader(http.StatusOK)
3 n, err := b.ResponseWriter.Write(buf)
4 if b.tee != nil {
5 _, err2 := b.tee.Write(buf[:n])
6 // Prefer errors generated by the proxied writer.
7 if err == nil {
8 err = err2
9 }
10 }
11 b.bytes += n
12 return n, err
13 }
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 26 / 29
49. Go interfaces limitations
No parametric polymorphism and limited Ad-hoc polymorphism.
In 99% of cases you won’t need it!
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 28 / 29
50. Go interfaces limitations
No parametric polymorphism and limited Ad-hoc polymorphism.
In 99% of cases you won’t need it!
Workaround: go generate
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 28 / 29
51. Go interfaces limitations
No parametric polymorphism and limited Ad-hoc polymorphism.
In 99% of cases you won’t need it!
Workaround: go generate
A real solution may come as soon as people will find an easy
polymorphic type system which will integrate well with go interfaces.
By now go generate is making a good job for this corner cases.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 28 / 29
52. Summary
A simple type system based on dynamic interfaces
provides a powerful tool for software architects which
will help design and maintain software systems.
Idea for OOP:
Unless you want to extend / wrap some object it may
be interesting to use only abstract inheritance in OOP.
Robert Zaremba (AgFlow) Simple polymorphism Wroclaw 2015-01-08 29 / 29