Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RailsConf 2017

RailsConf 2017

It's my keynote from RailsConf 2017

Aaron Patterson

May 05, 2017
Tweet

More Decks by Aaron Patterson

Other Decks in Programming

Transcript

  1. Hello RailsConf!

    View full-size slide

  2. Hi, I’m @tenderlove

    View full-size slide

  3. Le Gîte Hub

    View full-size slide

  4. Rails Core Team

    View full-size slide

  5. Ruby Core Team

    View full-size slide

  6. I have stickers!

    View full-size slide

  7. "Why Slack is inappropriate for
    open source communications"

    View full-size slide

  8. "We are, temporarily, in a kind
    of dark ages of end-user open
    source software."

    View full-size slide

  9. Oops, I died of plague
    This is a rat

    View full-size slide

  10. Electron is flash for the
    desktop

    View full-size slide

  11. "slack often idles at 5% CPU
    usage"

    View full-size slide

  12. "Buy a bigger CPU, ya dummy"

    View full-size slide

  13. Alan Turning

    View full-size slide

  14. HN on Language Features

    View full-size slide

  15. "No generics and no sum types?
    Those are no longer groundbreaking,
    they're the bare minimum.*"
    *Emphasis not mine

    View full-size slide

  16. No generics means your
    language is a failure

    View full-size slide

  17. Insurance companies only
    cover Generics

    View full-size slide

  18. Sorry, your
    language has been
    denied
    L'Hôpital

    View full-size slide

  19. #supportlocal

    View full-size slide

  20. Local Coffee!

    View full-size slide

  21. Trolling DHH:
    An Annual Tradition

    View full-size slide

  22. Faith Based Programmer

    View full-size slide

  23. "Pleaseworkpleaseworkpleas
    eworkpleaseworkpleasework"
    The Programmer’s Prayer

    View full-size slide

  24. 24 bit audio

    View full-size slide

  25. 10+ Years of Rails

    View full-size slide

  26. It was the year 2003

    View full-size slide

  27. What should I do with all this
    free time?

    View full-size slide

  28. "We’ve tried to charge your
    card hundreds of times"

    View full-size slide

  29. Technical Debt

    View full-size slide

  30. Developers want to pay off
    technical debt

    View full-size slide

  31. Managers do not want to
    pay off technical debt
    (if they can help it)

    View full-size slide

  32. Tech Debt
    Gem Gem
    Gem
    Gem
    Gem
    Meta Gem

    View full-size slide

  33. Tech Debt
    Gem Gem
    Gem
    Gem
    Gem
    "Bond"
    "Tranche"

    View full-size slide

  34. Tech Debt
    Gem Gem
    Gem
    Webpack
    Gem
    Rails

    View full-size slide

  35. Blood of
    young people

    View full-size slide

  36. Concatenating a bunch of
    strings

    View full-size slide

  37. Rails 5.1 is out!

    View full-size slide

  38. Thanks @rafaelfranca!!!

    View full-size slide

  39. I don’t have time for this
    Things I don’t have time for but would like to do

    View full-size slide

  40. Non-committal

    View full-size slide

  41. Humorous use of common
    phrase

    View full-size slide

  42. "No Pressure"

    View full-size slide

  43. ALL OF THE
    PRESSURE

    View full-size slide

  44. Searls - Briggs

    View full-size slide

  45. Fear & Self Doubt

    View full-size slide

  46. 5 things I don’t have time
    to do
    but you should do them for me

    View full-size slide

  47. What if I don’t have time to
    present 5 things??

    View full-size slide

  48. What if I want to talk about
    things I do have time for?

    View full-size slide

  49. Some things I don’t have
    time to do
    but you should do them for me
    Maybe like 3 things?

    View full-size slide

  50. Probably Important
    Definitely Not Important

    View full-size slide

  51. HTTP/2 + Rack
    A thing that I do have time for

    View full-size slide

  52. What is HTTP/2?

    View full-size slide

  53. 1 better than HTTP/1

    View full-size slide

  54. 0.9 better than HTTP/1.1

    View full-size slide

  55. HTTP/2 (really)
    • Binary protocol
    • Multiplexes (multiple requests on the same socket)
    • Secure (only works over SSL*)
    • Push responses

    View full-size slide

  56. Push Response Flow

    View full-size slide

  57. HTTP 1.1
    Time
    index.html
    jquery.js
    gorby.css
    Client Server

    View full-size slide

  58. HTTP 2
    Time
    index.html
    jquery.js
    gorby.css
    Client Server

    View full-size slide

  59. Save Time by Pushing
    "Needed" Resources

    View full-size slide

  60. H2 is still stateless

    View full-size slide

  61. HTTP 2
    Time
    index.html
    jquery.js
    gorby.css
    Client Server

    View full-size slide

  62. Double Assets
    • Client can cancel (requires round trip)
    • Resend assets (extra bandwidth)

    View full-size slide

  63. Solution: H2O + SALT
    Get it, "solution"????

    View full-size slide

  64. Solution: H2O + Cookies

    View full-size slide

  65. What is H2O?
    https://h2o.examp1e.net

    View full-size slide

  66. Server (Unicorn)
    Proxy (h2o)
    Client
    HTTP/2 HTTP/1.1

    View full-size slide

  67. H2 Pushes with HTTP/1.1

    View full-size slide

  68. Link Header
    200 OK
    Content-Length: 1024
    Content-Type: text/html
    Link: ; rel=preload
    Link: ; rel=preload
    response body

    View full-size slide

  69. Server (Unicorn)
    Proxy (h2o)
    Client
    HTTP/2 HTTP/1.1
    200 OK
    Content-Length: 1024
    Content-Type: text/html
    Link: ; rel=preload
    Link: ; rel=preload
    response body

    View full-size slide

  70. No state tracking in the app

    View full-size slide

  71. Link Header Problem
    200 OK
    Content-Length: 1024
    Content-Type: text/html
    Link: ; rel=preload
    Link: ; rel=preload
    response body

    View full-size slide

  72. 103 Early Hints

    View full-size slide

  73. 103 Early Response
    103 Early Hints
    Link: ; rel=preload
    Link: ; rel=preload
    200 OK
    Content-Length: 1024
    Content-Type: text/html
    response body

    View full-size slide

  74. Rack Support
    Rack 3.0

    View full-size slide

  75. New ENV hash key! ("yay")
    env['rack.push'].call(103, [
    ['Link', '/gorby.css']
    ], [])

    View full-size slide

  76. Backwards Compatibility

    View full-size slide

  77. Graceful Upgrade

    View full-size slide

  78. This is a talk about code
    smells

    View full-size slide

  79. Data I acquired (crap data)
    -100
    925
    1950
    2975
    4000
    Time
    2017-01-23
    15:53:51
    2017-01-23
    15:53:56
    2017-01-23
    15:54:01
    2017-01-23
    15:54:06
    2017-01-23
    15:54:11
    2017-01-23
    15:54:16
    2017-01-23
    15:54:21
    2017-01-23
    15:54:26
    2017-01-23
    15:54:31
    2017-01-23
    15:54:37
    2017-01-23
    15:54:42
    2017-01-23
    15:54:47
    2017-01-23
    15:54:52
    2017-01-23
    15:54:57
    2017-01-23
    15:55:02
    2017-01-23
    15:55:07
    2017-01-23
    15:55:12
    2017-01-23
    15:55:17
    2017-01-23
    15:55:22
    2017-01-23
    15:55:27
    2017-01-23
    15:55:32

    View full-size slide

  80. Ruby VM Tricks

    View full-size slide

  81. How a VM works

    View full-size slide

  82. VM
    [push, 4]
    [push, 3]
    [add]
    PC
    Program Stack
    4
    3
    7

    View full-size slide

  83. Implementation
    instructions = [
    [:push, 3],
    [:push, 7],
    [:add],
    ]
    pc = 0
    loop do
    instruction = instructions[pc]
    pc += 1
    send function_table[instruction.first]
    end

    View full-size slide

  84. Generate the VM

    View full-size slide

  85. Loop Elimination
    instructions = [ [:push, 3], [:push, 7], [:add], ]
    def push_op pc, val, instructions
    # code to push on the stack
    # ....
    next_instruction = instructions[pc]
    send(function_table[next_instruction.first]
    pc + 1,
    next_instruction,
    instructions)
    end
    def add pc, val, instructions
    # code to add
    # ....
    next_instruction = instructions[pc]
    send(function_table[next_instruction.first]
    pc + 1,
    next_instruction,
    instructions)
    end
    # start of VM
    pc = 0
    instruction = instructions[pc]
    pc += 1
    send function_table[instruction.first]
    Generated

    View full-size slide

  86. Function call elimination

    View full-size slide

  87. Function Name Lookup Table
    instructions = [ [:push, 3], [:push, 7], [:add], ]
    function_table = {
    :push => :push_op,
    :add => :add_op,
    }
    def push_op pc, val, instructions
    # code to push on the stack
    # ....
    next_instruction = instructions[pc]
    send(function_table[next_instruction.first]
    pc + 1,
    next_instruction,
    instructions)
    end

    View full-size slide

  88. JUMP
    instructions = [ [:push, 3], [:push, 7], [:add], ]
    function_table = {
    :push => ADDRESS_OF(:push_op),
    :add => ADDRESS_OF(:add_op),
    }
    label: :add_op
    # code to add
    # ...
    next_instruction = instructions[pc]
    val = next_instruction.drop(1)
    address = function_table[next_instruction.first]
    pc += 1
    GOTO(address)
    label: :push_op
    # code to push on the stack
    # ....
    next_instruction = instructions[pc]
    val = next_instruction.drop(1)
    address = function_table[next_instruction.first]
    pc += 1
    GOTO(address)
    Generated

    View full-size slide

  89. Lookup Table Elimination

    View full-size slide

  90. Addresses in Byte Code
    instructions = [
    [ADDRESS_OF(:push_op), 3],
    [ADDRESS_OF(:push_op), 7],
    [ADDRESS_OF(:add)],
    ]
    label: :add_op
    # code to add
    # ...
    next_instruction = instructions[pc]
    val = next_instruction.drop(1)
    address = next_instruction.first
    pc += 1
    GOTO(address)
    label: :push_op
    # code to push on the stack
    # ....
    next_instruction = instructions[pc]
    val = next_instruction.drop(1)
    address = next_instruction.first
    pc += 1
    GOTO(address)

    View full-size slide

  91. Direct Threaded VM

    View full-size slide

  92. Addresses are just integers

    View full-size slide

  93. MRI’s VM is Direct Threaded

    View full-size slide

  94. Create custom instructions built
    from machine code
    at runtime

    View full-size slide

  95. Extremely Simple Code
    require 'lolvm'
    class MyRuby
    attr_reader :rb_path2class, :rb_define_method, :mod
    def initialize ctx
    @mod = ctx.create_module 'ruby'
    @ctx = ctx
    init_functions
    end
    private
    def init_functions
    @rb_path2class = make_func('rb_path2class', @ctx.int8.pointer, [@ctx.int8.pointer])
    @rb_define_method = make_func('rb_define_method', @ctx.int8.pointer, [@ctx.int8.pointer, @ctx.int8.pointer, @ctx.int8.pointer, @ctx.int32])
    end
    def make_func name, ret, args
    func_type = LOLVM::Types::Function.new(ret, args, false)
    @mod.add_function name, func_type
    end
    end
    context = LOLVM::Context.instance
    builder = context.create_builder
    ruby = MyRuby.new context
    mod = context.create_module 'anon mod'
    func_type = LOLVM::Types::Function.new(context.double, [], false)
    testing = mod.add_function "testing", LOLVM::Types::Function.new(context.int64, [context.int8.pointer], false)
    testing.param(0).name = "foo"
    bb = context.append_basic_block testing, "entry"
    x = mod.add_global context.int64, 'rb_cObject'
    x.linkage = LOLVM::Linkages::External
    builder.position_at_end_of bb
    builder.ret builder.load x, "obj"
    func = mod.add_function "__anon", func_type
    bb = context.append_basic_block func, "entry"
    builder.position_at_end_of bb
    str = builder.global_string "MyRuby", 'string'
    func_name = builder.global_string "testing", 'func_name'
    my_ruby = builder.call testing, [str], 'rb_str'
    builder.ret my_ruby
    ee = mod.execution_engine
    ee.add_module ruby.mod
    p :GOT => ee.run("__anon")
    Assembles machine code
    at run time using LLVM

    View full-size slide

  96. Idea 1: Custom Instructions
    at Runtime

    View full-size slide

  97. Data I acquired (crap data)
    -100
    925
    1950
    2975
    4000
    Time
    2017-01-23
    15:53:51
    2017-01-23
    15:53:56
    2017-01-23
    15:54:01
    2017-01-23
    15:54:06
    2017-01-23
    15:54:11
    2017-01-23
    15:54:16
    2017-01-23
    15:54:21
    2017-01-23
    15:54:26
    2017-01-23
    15:54:31
    2017-01-23
    15:54:37
    2017-01-23
    15:54:42
    2017-01-23
    15:54:47
    2017-01-23
    15:54:52
    2017-01-23
    15:54:57
    2017-01-23
    15:55:02
    2017-01-23
    15:55:07
    2017-01-23
    15:55:12
    2017-01-23
    15:55:17
    2017-01-23
    15:55:22
    2017-01-23
    15:55:27
    2017-01-23
    15:55:32

    View full-size slide

  98. Build a Police Scanner

    View full-size slide

  99. Software Defined Radio

    View full-size slide

  100. Narrow FM
    Digital Trunking
    signal
    Audio

    View full-size slide

  101. Digital Signal Processing

    View full-size slide

  102. Continuous / Discrete
    Very Discrete
    tenderlove

    View full-size slide

  103. Discrete signals are just a list
    of points

    View full-size slide

  104. Discrete Signal (crap data)
    -100
    925
    1950
    2975
    4000
    Time
    2017-01-23
    15:53:51
    2017-01-23
    15:53:56
    2017-01-23
    15:54:01
    2017-01-23
    15:54:06
    2017-01-23
    15:54:11
    2017-01-23
    15:54:16
    2017-01-23
    15:54:21
    2017-01-23
    15:54:26
    2017-01-23
    15:54:31
    2017-01-23
    15:54:37
    2017-01-23
    15:54:42
    2017-01-23
    15:54:47
    2017-01-23
    15:54:52
    2017-01-23
    15:54:57
    2017-01-23
    15:55:02
    2017-01-23
    15:55:07
    2017-01-23
    15:55:12
    2017-01-23
    15:55:17
    2017-01-23
    15:55:22
    2017-01-23
    15:55:27
    2017-01-23
    15:55:32

    View full-size slide

  105. Signal Convolution
    -100
    925
    1950
    2975
    4000
    Time
    2017-01-23
    15:53:51
    2017-01-23
    15:54:01
    2017-01-23
    15:54:11
    2017-01-23
    15:54:21
    2017-01-23
    15:54:31
    2017-01-23
    15:54:42
    2017-01-23
    15:54:52
    2017-01-23
    15:55:02
    2017-01-23
    15:55:12
    2017-01-23
    15:55:22
    2017-01-23
    15:55:32
    0
    0.25
    0.5
    0.75
    1
    0 1 2 3 4 5 6 7
    * =?

    View full-size slide

  106. Formal Definition

    View full-size slide

  107. X
    -1.5
    -0.5
    0.5
    1.5
    0 1 2 3 4 5 6 7 8
    H
    -0.5
    0
    0.5
    1
    3 2 1 0
    Y
    -1.5
    0
    1.5
    3
    0 1 2 3 4 5 6 7 8 9 10 11

    View full-size slide

  108. Convolution Code
    def convolve x, h
    Array.new(x.length + h.length - 1) do |i|
    h.map.with_index { |h_j, j|
    if i - j < 0 || i - j > x.length - 1
    0
    else
    h_j * x[i - j]
    end
    }.inject(:+)
    end
    end

    View full-size slide

  109. Convolved Signal Length:
    x.length + h.length - 1

    View full-size slide

  110. X
    -1.5
    -0.5
    0.5
    1.5
    0 1 2 3 4 5 6 7 8
    H
    -0.5
    0
    0.5
    1
    3 2 1 0
    x
    + y[i] value

    View full-size slide

  111. Low Pass Filters

    View full-size slide

  112. Identity Signal
    X
    -1.5
    -0.5
    0.5
    1.5
    0 1 2 3 4 5 6 7 8
    H
    0
    0.25
    0.5
    0.75
    1
    0 1 2 3
    * =
    Y
    -1.5
    -0.5
    0.5
    1.5
    0 1 2 3 4 5 6 7 8 9 10 11

    View full-size slide

  113. Amplifier
    X
    -1.5
    -0.5
    0.5
    1.5
    0 1 2 3 4 5 6 7 8
    H
    0
    0.5
    1
    1.5
    2
    0 1 2 3
    * =
    Y
    -3
    -1
    1
    3
    0 2 4 6 8 10

    View full-size slide

  114. Shift
    X
    -1.5
    -0.5
    0.5
    1.5
    0 1 2 3 4 5 6 7 8
    H
    0
    0.25
    0.5
    0.75
    1
    0 1 2 3
    * =
    Y
    -1.5
    -0.5
    0.5
    1.5
    0 1 2 3 4 5 6 7 8 9 10 11

    View full-size slide

  115. Echo
    X
    -1.5
    -0.5
    0.5
    1.5
    0 1 2 3 4 5 6 7 8
    H
    0
    0.5
    1
    1.5
    2
    0 1 2 3
    * =
    Y
    -3.75
    -1.25
    1.25
    3.75
    0 1 2 3 4 5 6 7 8 9 10 11

    View full-size slide

  116. Average
    X
    -1.5
    -0.5
    0.5
    1.5
    0 1 2 3 4 5 6 7 8
    H
    0
    0.25
    0.5
    0.75
    1
    0 1 2 3
    * H
    0
    0.125
    0.25
    0.375
    0.5
    0 1 2 3
    *

    View full-size slide

  117. Radar
    Transmission
    0
    25
    50
    75
    100
    Reception
    -25
    0
    25
    50
    75
    100

    View full-size slide

  118. Does one signal contain the
    other?

    View full-size slide

  119. received * transmitted
    Detection
    -10000
    0
    10000
    20000
    30000
    40000

    View full-size slide

  120. Gaussian Distribution

    View full-size slide

  121. Self Convolution
    signal = 100.times.map { rand }
    3.times do
    signal = convolve signal, signal
    end

    View full-size slide

  122. Self Convolution
    Gaussian Distribution
    0
    75000000000
    150000000000
    225000000000
    300000000000
    Neat!
    tenderlove

    View full-size slide

  123. Convolution Code
    def convolve x, h
    Array.new(x.length + h.length - 1) do |i|
    h.map.with_index { |h_j, j|
    if i - j < 0 || i - j > x.length - 1
    0
    else
    h_j * x[i - j]
    end
    }.inject(:+)
    end
    end

    View full-size slide

  124. R, the hard way

    View full-size slide

  125. Arrays are 1 based
    > data <- c(4, 3, 2, 1)
    > data[0]
    numeric(0)
    > data[0] + 1
    numeric(0)
    >

    View full-size slide

  126. There must be an
    easier way!
    tenderlove

    View full-size slide

  127. Data I acquired (crap data)
    -100
    925
    1950
    2975
    4000
    Time
    2017-01-23
    15:53:51
    2017-01-23
    15:53:56
    2017-01-23
    15:54:01
    2017-01-23
    15:54:06
    2017-01-23
    15:54:11
    2017-01-23
    15:54:16
    2017-01-23
    15:54:21
    2017-01-23
    15:54:26
    2017-01-23
    15:54:31
    2017-01-23
    15:54:37
    2017-01-23
    15:54:42
    2017-01-23
    15:54:47
    2017-01-23
    15:54:52
    2017-01-23
    15:54:57
    2017-01-23
    15:55:02
    2017-01-23
    15:55:07
    2017-01-23
    15:55:12
    2017-01-23
    15:55:17
    2017-01-23
    15:55:22
    2017-01-23
    15:55:27
    2017-01-23
    15:55:32

    View full-size slide

  128. Implementing cons, car,
    and cdr in many languages
    (using only lambdas)

    View full-size slide

  129. I like learning new languages

    View full-size slide

  130. But I don’t have much time

    View full-size slide

  131. Bare minimum to get
    endorsed on Linked In
    Do people still use Klout?

    View full-size slide

  132. What are cons, car, and cdr?

    View full-size slide

  133. cons forms a cell
    L R

    View full-size slide

  134. car returns the left side
    L R

    View full-size slide

  135. cdr returns the right side
    L R

    View full-size slide

  136. Only Lambdas?

    View full-size slide

  137. cons
    tenderlove.cons <- function(x, y) {
    function(m) { m(x, y) }
    }
    R
    Node
    cons = ->(x, y) {
    ->(m) { m.(x, y) }
    }
    Ruby
    var cons = function(x, y) {
    return function(m) { return m(x, y); };
    }

    View full-size slide

  138. car
    tenderlove.car <- function(z) {
    z(function(p, q) { p })
    }
    R
    var car = function(z) {
    return z(function(p, q) { return p; });
    }
    Node
    car = ->(z) {
    z.(->(p, q) { p })
    }
    Ruby

    View full-size slide

  139. Usage
    > tenderlove.cons(1, 2)
    function(m) { m(x, y) }

    > tenderlove.car
    function(z) { z(function(p, q) { p }) }
    > tenderlove.car(tenderlove.cons(1, 2))
    [1] 1
    >

    View full-size slide

  140. cdr
    tenderlove.cdr <- function(z) {
    z(function(p, q) { q })
    }
    R
    var cdr = function(z) {
    return z(function(p, q) { return q; });
    }
    Node
    cdr = ->(z) {
    z.(->(p, q) { q })
    }
    Ruby

    View full-size slide

  141. Tree of Cells
    1
    2
    3 NUL

    View full-size slide

  142. each
    tenderlove.each <- function(func, lst) {
    if (!is.null(lst)) {
    element <- tenderlove.car(lst)
    func(element)
    tenderlove.each(func, tenderlove.cdr(lst))
    }
    }
    R
    Node
    each = ->(func, list) {
    if list
    element = car.(list)
    func.(element)
    each.(func, cdr.(list))
    end
    }
    Ruby
    var each = function(func, list) {
    if(list) {
    element = car(list);
    func(element);
    each(func, cdr(list));
    }
    }

    View full-size slide

  143. Usage
    var each = function(func, list) {
    if(list) {
    element = car(list);
    func(element);
    each(func, cdr(list));
    }
    }
    each(console.log, cons(1, (cons(2, cons(3, null)))));
    [aaron@TC dsp (master)]$ node dsp.js
    1
    2
    3
    [aaron@TC dsp (master)]$

    View full-size slide

  144. Don’t need loops

    View full-size slide

  145. Don’t need arrays

    View full-size slide

  146. Don’t need hashes

    View full-size slide

  147. Numbers
    tenderlove.zero <- function(f) {
    function(x) { x }
    }
    tenderlove.one <- function(f) {
    function(x) { f(x) }
    }
    tenderlove.two <- function(f) {
    function(x) { f(f(x)) }
    }
    tenderlove.three <- function(f) {
    function(x) { f(f(f(x))) }
    }
    print(tenderlove.three(function(x) { x + 1 })(0)) => 3

    View full-size slide

  148. Addition
    tenderlove.one <- function(f) {
    function(x) { f(x) }
    }
    tenderlove.add <- function(a, b) {
    function(f) { function(x) { a(f)(b(f)(x)) } }
    }
    tenderlove.two <- tenderlove.add(tenderlove.one, tenderlove.one)
    tenderlove.three <- tenderlove.add(tenderlove.one, tenderlove.two)
    print(tenderlove.three(function(x) { x + 1 })(0)) # => 3

    View full-size slide

  149. Church Encoding

    View full-size slide

  150. Don’t need Numbers

    View full-size slide

  151. Don’t need Mathematics

    View full-size slide

  152. true / false / if
    True = ->(x, y) { x }
    False = ->(x, y) { y }
    If = ->(cond, t, f) { cond.(t, f) }
    If.(True, ->() { :true }, ->() { :false }).call # => :true
    If.(False, ->() { :true }, ->() { :false }).call # => :false

    View full-size slide

  153. Don’t need booleans

    View full-size slide

  154. Don’t need conditionals

    View full-size slide

  155. My Signal (crap data)
    -100
    925
    1950
    2975
    4000
    Time
    2017-01-23
    15:53:51
    2017-01-23
    15:53:56
    2017-01-23
    15:54:01
    2017-01-23
    15:54:06
    2017-01-23
    15:54:11
    2017-01-23
    15:54:16
    2017-01-23
    15:54:21
    2017-01-23
    15:54:26
    2017-01-23
    15:54:31
    2017-01-23
    15:54:37
    2017-01-23
    15:54:42
    2017-01-23
    15:54:47
    2017-01-23
    15:54:52
    2017-01-23
    15:54:57
    2017-01-23
    15:55:02
    2017-01-23
    15:55:07
    2017-01-23
    15:55:12
    2017-01-23
    15:55:17
    2017-01-23
    15:55:22
    2017-01-23
    15:55:27
    2017-01-23
    15:55:32

    View full-size slide

  156. cons / car / cdr / each
    tenderlove.cons <- function(x, y) { function(m) { m(x, y) } }
    tenderlove.car <- function(z) { z(function(p, q) { p }) }
    tenderlove.cdr <- function(z) { z(function(p, q) { q }) }
    tenderlove.each <- function(func, lst) {
    if (!is.null(lst)) {
    element <- tenderlove.car(lst)
    func(element)
    tenderlove.each(func, tenderlove.cdr(lst))
    }
    }
    tenderlove.each_with_index <- function(func, lst) {
    idx <- 0
    tenderlove.each(function(element) {
    func(idx, element)
    idx = idx + 1
    }, lst)
    }

    View full-size slide

  157. array indexing
    tenderlove.vec_at <- function(idx, lst) {
    if(idx == 0) {
    tenderlove.car(lst)
    } else {
    tenderlove.vec_at(idx - 1, tenderlove.cdr(lst))
    }
    }

    View full-size slide

  158. Converting Vectors to cons
    tenderlove.c2cons <- function(cs) {
    foldl <- function(proc, init, lst) {
    if(length(lst) == 0) {
    init
    } else {
    foldl(proc, proc(head(lst, 1), init), tail(lst, -1))
    }
    }
    foldl(tenderlove.cons, NULL, rev(cs))
    }

    View full-size slide

  159. Convolution in R
    tenderlove.conv <- function(x, h) {
    x_list <- tenderlove.c2cons(x)
    h_list <- tenderlove.c2cons(h)
    indexes <- 0:(length(x) + length(h) - 1)
    sapply(indexes, function(i) {
    sum(tenderlove.cons2c(tenderlove.map_with_index(function(j, h_j) {
    if (i - j < 0 || i - j > length(x) - 1) {
    0
    } else {
    h_j * tenderlove.vec_at(i - j, x_list)
    }
    }, h_list)))
    })
    }

    View full-size slide

  160. Feed in test data
    > data <- c(0, -1, -1.2, 2, 1.5, 1.4, 0.5, 0, -0.5)
    > plot(data)
    > filter <- c(2, 0, 1)
    > plot(filter)
    > plot(tenderlove.conv(data, filter))

    View full-size slide

  161. * =
    Nice.
    tenderlove

    View full-size slide

  162. Input Real Data
    > plot(tenderlove.conv(unlist(dat$V2), c(1)))
    Error: evaluation nested too deeply: infinite
    recursion / options(expressions=)?
    I f#$@*ing hate R.
    tenderlove

    View full-size slide

  163. Things I don’t have time for:
    Figuring out R.

    View full-size slide

  164. My Signal (crap data)
    -100
    925
    1950
    2975
    4000
    Time
    2017-01-23
    15:53:51
    2017-01-23
    15:53:56
    2017-01-23
    15:54:01
    2017-01-23
    15:54:06
    2017-01-23
    15:54:11
    2017-01-23
    15:54:16
    2017-01-23
    15:54:21
    2017-01-23
    15:54:26
    2017-01-23
    15:54:31
    2017-01-23
    15:54:37
    2017-01-23
    15:54:42
    2017-01-23
    15:54:47
    2017-01-23
    15:54:52
    2017-01-23
    15:54:57
    2017-01-23
    15:55:02
    2017-01-23
    15:55:07
    2017-01-23
    15:55:12
    2017-01-23
    15:55:17
    2017-01-23
    15:55:22
    2017-01-23
    15:55:27
    2017-01-23
    15:55:32

    View full-size slide

  165. Something I built

    View full-size slide

  166. Bathroom Scale

    View full-size slide

  167. Raspberry Pi + Motion Sensor

    View full-size slide

  168. I made this
    Weight (g)
    -100
    925
    1950
    2975
    4000
    Time
    2017-01-23
    15:53:51
    2017-01-23
    15:53:56
    2017-01-23
    15:54:01
    2017-01-23
    15:54:06
    2017-01-23
    15:54:11
    2017-01-23
    15:54:16
    2017-01-23
    15:54:21
    2017-01-23
    15:54:26
    2017-01-23
    15:54:31
    2017-01-23
    15:54:37
    2017-01-23
    15:54:42
    2017-01-23
    15:54:47
    2017-01-23
    15:54:52
    2017-01-23
    15:54:57
    2017-01-23
    15:55:02
    2017-01-23
    15:55:07
    2017-01-23
    15:55:12
    2017-01-23
    15:55:17
    2017-01-23
    15:55:22
    2017-01-23
    15:55:27
    2017-01-23
    15:55:32
    Cat Enters Cat Leaves

    View full-size slide

  169. It’s hard to make shit scale
    I told you those graphs were crap

    View full-size slide