73
Introducing HDD @elixirlang / elixir-lang.org

2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Introducing HDD

@elixirlang / elixir-lang.org

Page 2: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Elixir v1.6

• January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Page 3: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Code Formatter

Page 4: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

defmodule DemoWeb.PostController do use DemoWeb,:controller

alias Demo.Blog alias Demo.Blog.Post

def create(conn,%{"post"=>post_params}) do

case Blog.create_post(post_params) do

{:ok,post} -> conn |> put_flash(:info,"Post created successfully.") |> redirect(to: post_path(conn, :show, post))

{:error,%Ecto.Changeset{}=changeset} -> render(conn,"new.html",changeset: changeset)

end

end

Page 5: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

defmodule DemoWeb.PostController do use DemoWeb, :controller

alias Demo.Blog alias Demo.Blog.Post

def create(conn, %{"post" => post_params}) do case Blog.create_post(post_params) do {:ok, post} -> conn |> put_flash(:info, "Post created successfully.") |> redirect(to: post_path(conn, :show, post))

{:error, %Ecto.Changeset{} = changeset} -> render(conn, "new.html", changeset: changeset) end end

Page 6: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Elixir v1.7

• July/2018 • ??? contributors • ??? packages on hex.pm • ??? downloads

Page 7: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

StreamData

Page 8: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

iex> import Stream.Data

iex> Enum.take integer(), 10 [1, -2, -1, 2, 0, 6, 1, 8, -6, 3]

iex> Enum.take string(:ascii), 10 ["C", "", "", "1I", "dkrov", "dR4", "T4=h4", "u", "_gjE", "K^u5eJ&7"]

Data generation

Page 9: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Property-based testingcheck all left <- string(), right <- string(), string = left <> right do

assert String.contains?(string, left) assert String.contains?(string, right)

end

Page 10: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

John Hughes

Page 11: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Code Formatter

Page 12: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Code Formatter• Formats your code using a consistent style • Helps you focus on what matters • Works as a guide for newcomers • Unifies code written by teams and the

community

Page 13: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads
Page 14: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Code Formatter principles

1. It does not change the code semantics by default

2. Minimize configuration 3. No special cases

Page 15: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

mix format

Page 16: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

[a: [1, 2, 3], b: :ok]

Page 17: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

[a: [1, 2, 3], b: :ok]

25

Page 18: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

[a: [1, 2, 3], b: :ok]

20

Page 19: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

[ a: [1, 2, 3], b: :ok ]

20

Page 20: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

[ a: [1, 2, 3], b: :ok ]

10

Page 21: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

[ a: [ 1, 2, 3 ], b: :ok ]

10

Page 22: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Document Algebra

Page 23: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads
Page 24: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Documents• "text" • nest(doc, columns) • line(doc, doc) • concat(doc, doc) • empty()

Page 25: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

"[" |> concat("1,") |> concat("2,") |> concat("3") |> concat("]")

[1,2,3]

Page 26: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

"[" |> line("1,") |> line("2,") |> line("3") |> nest(2) |> line("]")

[ 1, 2, 3 ]

Page 27: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

How to choose between layouts?

Page 28: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

"[" |> concat("1,") |> concat("2,") |> concat("3,") |> nest(2) |> concat("]")

[1,2,3]

Page 29: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

"[" |> line("1,") |> line("2,") |> line("3") |> nest(2) |> line("]")

[ 1, 2, 3 ]

Page 30: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads
Page 31: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

group( "[" |> line("1,") |> line("2,") |> line("3") |> nest(2) |> line("]") )

Flexible layout

Page 32: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

def group(doc) do choose( replace_line_by_concat(doc), doc ) end

Flexible layout

Page 33: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

"[" |> concat("1,") |> concat("2,") |> concat("3") |> nest(2) |> concat("]")

[1,2,3][ 1, 2, 3 ]

"[" |> line("1,") |> line("2,") |> line("3") |> nest(2) |> line("]")

Page 34: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads
Page 35: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads
Page 36: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

def group(doc) do choose( replace_line_by_concat(doc), doc ) end

Lazy vs Eager

Page 37: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

[a: [1, 2, 3], b: :ok]

25

Page 38: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

[ a: [ 1, 2, 3 ], b: :ok ]

10

Page 39: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

[a: [1, 2, 3], b: :ok]

Page 40: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

def group(doc) do choose( replace_line_by_concat(doc), doc ) end

Lazy vs Eager

Page 41: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads
Page 42: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads
Page 43: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Document Algebra

• Implemented by Inspect.Algebra • Used to Inspect data structures • Used by the Code Formatter

Page 44: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

code([1, 2, 3], :ok)

25

Page 45: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

20

code([1, 2, 3], :ok)

Page 46: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

code( [1, 2, 3], :ok )

20

Page 47: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

10

code( [1, 2, 3], :ok )

Page 48: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

code( [ 1, 2, 3 ], :ok )

10

Page 49: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Extensions

• color(doc, color) • nest(doc, :cursor) • force_unfit(doc) • etc

Page 50: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

code(:ok, """ foo """, some_arg)

25force_unfit(doc)

Page 51: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

code( :ok, """ foo """, some_arg )

25force_unfit(doc)

Page 52: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

StreamData

Page 53: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Example-based testing

assert String.contains?("foobar", "foo") assert String.contains?("foobar", "bar") assert String.contains?("foobar", "ob") refute String.contains?("foobar", "oops")

Page 54: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Example-based testing

• How to find corner cases? • And how to reason about them?

Page 55: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Example-based testing

String.contains?("foobar", "") String.contains?("", "foobar") String.contains?("", "")

Page 56: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Property-based testingcheck all left <- string(), right <- string(), string = left <> right do

assert String.contains?(string, left) assert String.contains?(string, right)

end

Page 57: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Property-based testing• Described as generative testing • Useful to describe the invariants in

the system • Leads to thoroughly tested software

that is designed with intent

Page 58: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads
Page 59: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads
Page 60: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

iex> import Stream.Data

iex> Enum.take integer(), 10 [1, -2, -1, 2, 0, 6, 1, 8, -6, 3]

iex> Enum.take string(:ascii), 10 ["C", "", "", "1I", "dkrov", "dR4", "T4=h4", "u", "_gjE", "K^u5eJ&7"]

Generators…

Page 61: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

…are lazy

iex> integer() #StreamData<45.79517404/2 in StreamData.integer/0>

Page 62: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

…are infinite

iex> integer() |> Enum.to_list() ...takes forever...

Page 63: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

…are random

iex> integer() |> Enum.take(10) [1, -2, -1, 2, 0, 6, 1, 8, -6, 3]

iex> integer() |> Enum.take(10) [-1, 1, -1, 3, 5, 5, -1, -8, 3, 9]

Page 64: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

…grow in size

iex> integer() ...> |> Stream.drop(100) ...> |> Enum.take(10) [-96, -11, 100, -65, -41, -71, -81, 88, -54, -9]

Page 65: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Property-based testingcheck all left <- string(), right <- string(), string = left <> right do

assert String.contains?(string, left) assert String.contains?(string, right)

end

Page 66: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Generators are shrinkable

property "element not in list" do check all list <- list_of(integer()) do assert 22 not in list end end

Page 67: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

1) property element not in list (Test) examples/examples_test.exs:15 Failed with generated values (after 29 successful run(s)):

Clause: list <- list_of(integer()) Generated: [22]

Expected truthy, got false code: assert 22 not in list

Generators are shrinkable

Page 68: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Generators are functions

fn seed, size -> {current_element, shrinking_recipe} end

Page 69: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

StreamData• Provides data generation primitives • Brings stateless property-based

testing to ExUnit • QuickCheck provides more advanced

features such as model checking

Page 70: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads
Page 71: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

Hughes Driven

Development

Page 72: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

consulting and software engineering

Page 73: 2018.02.22 - HDD @ Lambda Days · Elixir v1.6 • January/2018 • >702 contributors • >5800 packages on hex.pm • >175 000 000 downloads

@elixirlang / elixir-lang.org