Slide 1

Slide 1 text

Oden A Functional Programming Language for the Go Ecosystem Oskar Wickström @owickstrom

Slide 2

Slide 2 text

http://empear.com @owickstrom

Slide 3

Slide 3 text

Agenda • Background • Project Goals • Current State • What’s next? • Questions @owickstrom

Slide 4

Slide 4 text

Background @owickstrom

Slide 5

Slide 5 text

Things I’ve been thinking about lately @owickstrom

Slide 6

Slide 6 text

I want type-safe functional programming for writing web applications. @owickstrom

Slide 7

Slide 7 text

Haskell is a great language. @owickstrom

Slide 8

Slide 8 text

Can we have the safety of Haskell, but in a smaller and simpler language? @owickstrom

Slide 9

Slide 9 text

I want fast, "clean slate" compilation as an option. @owickstrom

Slide 10

Slide 10 text

We should optimize for writing code that is correct, understandable, and safe to change. @owickstrom

Slide 11

Slide 11 text

We should not optimize for cleverness. @owickstrom

Slide 12

Slide 12 text

Maybe static typing on top of Javascript? @owickstrom

Slide 13

Slide 13 text

Having to write FFI bindings to use libraries is cumbersome. Can the compiler do this for us? @owickstrom

Slide 14

Slide 14 text

Can we reuse all the good stuff from Go, but use a functional language? @owickstrom

Slide 15

Slide 15 text

Yes, we can! @owickstrom

Slide 16

Slide 16 text

Why Go? • Ecosystem of libraries and tools • Goroutines, channels • Cross-compilation • Static linking • Simple compile target • Fast compiler @owickstrom

Slide 17

Slide 17 text

What I’m missing in Go @owickstrom

Slide 18

Slide 18 text

Expressions over statements @owickstrom

Slide 19

Slide 19 text

Generic Programming @owickstrom

Slide 20

Slide 20 text

Abstraction @owickstrom

Slide 21

Slide 21 text

func (c *dropboxClient) GetFile(accessToken, dropboxSrc, localTarget string) error { url : "https://content.dropboxapi.com/ /files/auto" dropboxSrc req, err : http.NewRequest("GET", url, nil) req.Header.Add("Authorization", "Bearer " accessToken) if err ! nil { return err } client : &http.Client{} res, err : client.Do(req) if err ! nil { return err } if res.StatusCode { return ErrNotFound } if res.StatusCode || res.StatusCode { return errors.New("Dropbox request failed: " res.Status) } f, err : os.Create(localTarget) if err ! nil { return err } io.Copy(f, res.Body) if err ! nil { return err } return nil } @owickstrom

Slide 22

Slide 22 text

func (c *dropboxClient) GetFile(accessToken, dropboxSrc, localTarget string) error { url : "https://content.dropboxapi.com/ /files/auto" dropboxSrc req, err : http.NewRequest("GET", url, nil) req.Header.Add("Authorization", "Bearer " accessToken) if err ! nil { return err } client : &http.Client{} res, err : client.Do(req) if err ! nil { return err } if res.StatusCode { return ErrNotFound } if res.StatusCode || res.StatusCode { return errors.New("Dropbox request failed: " res.Status) } f, err : os.Create(localTarget) if err ! nil { return err } io.Copy(f, res.Body) if err ! nil { return err } return nil } @owickstrom

Slide 23

Slide 23 text

if err ! nil { return err } @owickstrom

Slide 24

Slide 24 text

... f, err : os.Create(localTarget) if err ! nil { return err } io.Copy(f, res.Body) if err ! nil { return err } return nil } @owickstrom

Slide 25

Slide 25 text

Project Goals @owickstrom

Slide 26

Slide 26 text

Use Go as a platform @owickstrom

Slide 27

Slide 27 text

Avoid cleverness, prefer clarity @owickstrom

Slide 28

Slide 28 text

Expressions over statements @owickstrom

Slide 29

Slide 29 text

Support generic programming @owickstrom

Slide 30

Slide 30 text

Support good abstractions @owickstrom

Slide 31

Slide 31 text

Type inference @owickstrom

Slide 32

Slide 32 text

Immutability by default @owickstrom

Slide 33

Slide 33 text

Pattern matching @owickstrom

Slide 34

Slide 34 text

Exhaustiveness checking @owickstrom

Slide 35

Slide 35 text

Simple interoperability with Go @owickstrom

Slide 36

Slide 36 text

Fun! @owickstrom

Slide 37

Slide 37 text

Open-source from the beginning @owickstrom

Slide 38

Slide 38 text

Figure: MVP Pyramid @owickstrom

Slide 39

Slide 39 text

Current State @owickstrom

Slide 40

Slide 40 text

Hello World package main main() println("Hello World") @owickstrom

Slide 41

Slide 41 text

Operators !true - * / ( - ) / * -( ) ! "Foo" "Bar" false && (true || ( )) @owickstrom

Slide 42

Slide 42 text

Operator Desugaring Operator Protocol Method - Num Negate ! Logical Not Num Add - Num Subtract * Num Multiply / Num Divide && Logical Conjunction || Logical Disjunction Monoid Apply @owickstrom

Slide 43

Slide 43 text

No custom operators @owickstrom

Slide 44

Slide 44 text

No macros @owickstrom

Slide 45

Slide 45 text

Curried Functions plus(x, y) x y twice(f, x) f(f(x)) plusTwenty twice(plus( )) forty plusTwenty( ) @owickstrom

Slide 46

Slide 46 text

Curried Functions with Type Signatures plus : int - int - int plus(x, y) x y twice : forall a. (a - a) - a - a twice(f, x) f(f(x)) plusTwenty : int - int plusTwenty twice(plus( )) forty : int forty plusTwenty( ) @owickstrom

Slide 47

Slide 47 text

Imports from Go package main import html main() { println(html.EscapeString("Simon & Garfunkel")) // Simon & Garfunkel } @owickstrom

Slide 48

Slide 48 text

Imports from Go package main import foreign "html" main() { println(html.EscapeString("Simon & Garfunkel")) // Simon & Garfunkel } @owickstrom

Slide 49

Slide 49 text

Records sweden { official "Kingdom Of Sweden", population , capital "Stockholm" } usa { official "United States of America", population , capital "Washington D.C." } @owickstrom

Slide 50

Slide 50 text

Record Types sweden : { official : string, population : int, capital : string } @owickstrom

Slide 51

Slide 51 text

Records and Row Polymorphism fullName(person) person.firstName " " person.lastName @owickstrom

Slide 52

Slide 52 text

Records and Row Polymorphism fullName : forall r. { firstName : string, lastName : string | r } - string @owickstrom

Slide 53

Slide 53 text

Protocols Spoiler: Very similar to type classes @owickstrom

Slide 54

Slide 54 text

Protocols impl Monoid({ x: int, y: int }) { Apply(p , p ) { x p .x p .x, y p .y p .y } Identity { x , y } } @owickstrom

Slide 55

Slide 55 text

Protocols position { x , y } distance { x , y } target Monoid::Apply(position, distance) @owickstrom

Slide 56

Slide 56 text

Protocols position { x , y } distance { x , y } target position distance @owickstrom

Slide 57

Slide 57 text

Procotols are not simple @owickstrom

Slide 58

Slide 58 text

That’s not all @owickstrom

Slide 59

Slide 59 text

Finding more information @owickstrom

Slide 60

Slide 60 text

oden-lang.org @owickstrom

Slide 61

Slide 61 text

oden-lang.org/user-guide/latest/ @owickstrom

Slide 62

Slide 62 text

playground.oden-lang.org @owickstrom

Slide 63

Slide 63 text

@odenlang @owickstrom

Slide 64

Slide 64 text

What’s next? @owickstrom

Slide 65

Slide 65 text

Thank you! @owickstrom