Oden – A Functional Programming Language for the Go Ecosystem (PolyConf 2016)

Oden – A Functional Programming Language for the Go Ecosystem (PolyConf 2016)

This talk will introduce Oden, an experimental, statically typed, functional programming language built for the Go ecosystem. We will look at how Oden aims to leverage the great features of Go — static linking, cross-compilation, goroutines, channels and the great set of libraries and tools — and enable higher-level abstractions, generics and a safer yet more flexible type system.

Be279c8e94a0825d7c982e745a3b3ba9?s=128

Oskar Wickström

June 30, 2016
Tweet

Transcript

  1. Oden A Functional Programming Language for the Go Ecosystem Oskar

    Wickström (@owickstrom)
  2. Agenda • Background • Project Goals • Current State •

    What’s next? • Questions
  3. Background

  4. Things I’ve been thinking about lately

  5. I want type-safe functional programming for writing servers.

  6. Haskell is a great language.

  7. Can we have the safety of Haskell, but in a

    smaller and simpler language?
  8. Do I really need interactive development? How much complexity does

    the REPL bring?
  9. We should optimize for writing code that is correct, readable,

    and safe to change.
  10. We should not optimize for cleverness.

  11. Maybe static typing on top of Javascript?

  12. Having to write FFI bindings to use libraries is cumbersome.

    Can the compiler do this for us?
  13. Can we reuse all the good stuff from Go, but

    use a functional language?
  14. Yes, we can!

  15. Why Go? • Ecosystem of libraries and tools • Goroutines,

    channels • Cross-compilation • Static linking • Simple compile target • Fast compiler
  16. What I’m missing in Go

  17. Expressions over statements

  18. Generic Programming

  19. Abstraction

  20. 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 }
  21. 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 }
  22. if err ! nil { return err }

  23. ... f, err : os.Create(localTarget) if err ! nil {

    return err } io.Copy(f, res.Body) if err ! nil { return err } return nil }
  24. Project Goals

  25. Use Go as a platform

  26. Avoid cleverness, prefer clarity

  27. Expressions over statements

  28. Support generic programming

  29. Support good abstractions

  30. Type inference

  31. Immutability by default

  32. Pattern matching

  33. Exhaustiveness checking

  34. Simple interoperability with Go

  35. Fun!

  36. Open-source from the beginning

  37. Figure: MVP Pyramid

  38. Current State

  39. Hello World package main main() println("Hello World")

  40. Operators - * / ( - ) / * (

    ) ! "Foo" "Bar" false && (true || ( ))
  41. Operator Desugaring Operator Protocol Method - Num Negate ! Logical

    Not Num Add - Num Subtract * Num Multiply / Num Divide && Logical Conjunction || Logical Disjunction Monoid Apply
  42. No custom operators

  43. Curried Functions plus(x, y) x y twice(f, x) f(f(x)) plusTwenty

    twice(plus( )) forty plusTwenty( )
  44. 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( )
  45. Imports from Go package main import html main() { println(html.EscapeString("Simon

    & Garfunkel")) // Simon & Garfunkel }
  46. Records sweden { official "Kingdom Of Sweden", population , capital

    "Stockholm" } usa { official "United States of America", population , capital "Washington D.C." }
  47. Record Types sweden : { official : string, population :

    int, capital : string }
  48. Records and Row Polymorphism fullName(person) person.firstName " " person.lastName

  49. Records and Row Polymorphism fullName : forall r. { firstName

    : string, lastName : string | r } - string
  50. Protocols Spoiler: Very similar to type classes

  51. Protocols impl Monoid({ x: int, y: int }) { Apply(p

    , p ) { x p .x p .x, y p .y p .y } Identity { x , y } }
  52. Protocols position { x , y } distance { x

    , y } target Monoid::Apply(position, distance)
  53. Protocols position { x , y } distance { x

    , y } target position distance
  54. Finding more information

  55. oden-lang.org

  56. oden-lang.org/user-guide/latest/

  57. playground.oden-lang.org

  58. @odenlang

  59. What’s next?

  60. Thank you!