Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Hello ICON!

Slide 3

Slide 3 text

Hello RailsConf!

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Hi, I’m @tenderlove

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

h GitHub

Slide 8

Slide 8 text

Le Git

Slide 9

Slide 9 text

Le Gîte Hub

Slide 10

Slide 10 text

Rails Core Team

Slide 11

Slide 11 text

Ruby Core Team

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

I have stickers!

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

"Why Slack is inappropriate for open source communications"

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

Oops, I died of plague This is a rat

Slide 23

Slide 23 text

Electron is flash for the desktop

Slide 24

Slide 24 text

"slack often idles at 5% CPU usage"

Slide 25

Slide 25 text

CPU Slack

Slide 26

Slide 26 text

"Buy a bigger CPU, ya dummy"

Slide 27

Slide 27 text

Alan Turning

Slide 28

Slide 28 text

HN on Language Features

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

No generics means your language is a failure

Slide 31

Slide 31 text

Insurance companies only cover Generics

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

#supportlocal

Slide 36

Slide 36 text

Local Coffee!

Slide 37

Slide 37 text

Local Tea!

Slide 38

Slide 38 text

Trolling DHH: An Annual Tradition

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

Faith Based Programmer

Slide 42

Slide 42 text

"Pleaseworkpleaseworkpleas eworkpleaseworkpleasework" The Programmer’s Prayer

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

24 bit audio

Slide 46

Slide 46 text

10+ Years of Rails

Slide 47

Slide 47 text

It was the year 2003

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

What should I do with all this free time?

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

Technical Debt

Slide 52

Slide 52 text

Developers want to pay off technical debt

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

Tech Debt Gem Gem Gem Gem Gem Meta Gem

Slide 55

Slide 55 text

Tech Debt Gem Gem Gem Gem Gem "Bond" "Tranche"

Slide 56

Slide 56 text

Tech Debt Gem Gem Gem Webpack Gem Rails

Slide 57

Slide 57 text

Blood of young people

Slide 58

Slide 58 text

Concatenating a bunch of strings

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

Not a Joke

Slide 63

Slide 63 text

5

Slide 64

Slide 64 text

5

Slide 65

Slide 65 text

$5

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

5.1

Slide 68

Slide 68 text

Rails 5.1 is out!

Slide 69

Slide 69 text

Thanks @rafaelfranca!!! ❤

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

Non-committal

Slide 72

Slide 72 text

Humorous use of common phrase

Slide 73

Slide 73 text

"No Pressure"

Slide 74

Slide 74 text

ALL OF THE PRESSURE

Slide 75

Slide 75 text

Searls - Briggs

Slide 76

Slide 76 text

STRESS

Slide 77

Slide 77 text

Fear & Self Doubt

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

Probably Important Definitely Not Important

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

What is HTTP/2?

Slide 85

Slide 85 text

1 better than HTTP/1

Slide 86

Slide 86 text

0.9 better than HTTP/1.1

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

Push Response Flow

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

Save Time by Pushing "Needed" Resources

Slide 92

Slide 92 text

H2 Problems

Slide 93

Slide 93 text

H2 is still stateless

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

Solution: H2O + Cookies

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

H2 Pushes with HTTP/1.1

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

No state tracking in the app

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

103 Early Hints

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

Rack Support Rack 3.0

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

Backwards Compatibility

Slide 110

Slide 110 text

Graceful Upgrade

Slide 111

Slide 111 text

Rack 3.0

Slide 112

Slide 112 text

This is a talk about code smells

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

Ruby VM Tricks

Slide 115

Slide 115 text

How a VM works

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

Generate the VM

Slide 119

Slide 119 text

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

Slide 120

Slide 120 text

Threaded VM

Slide 121

Slide 121 text

Function call elimination

Slide 122

Slide 122 text

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

Slide 123

Slide 123 text

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

Slide 124

Slide 124 text

Lookup Table Elimination

Slide 125

Slide 125 text

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)

Slide 126

Slide 126 text

Direct Threaded VM

Slide 127

Slide 127 text

Addresses are just integers

Slide 128

Slide 128 text

MRI’s VM is Direct Threaded

Slide 129

Slide 129 text

Create custom instructions built from machine code at runtime

Slide 130

Slide 130 text

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

Slide 131

Slide 131 text

Idea 1: Custom Instructions at Runtime

Slide 132

Slide 132 text

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

Slide 133

Slide 133 text

Build a Police Scanner

Slide 134

Slide 134 text

No content

Slide 135

Slide 135 text

Software Defined Radio

Slide 136

Slide 136 text

No content

Slide 137

Slide 137 text

FM Band

Slide 138

Slide 138 text

Narrow FM Digital Trunking signal Audio

Slide 139

Slide 139 text

Digital Signal Processing

Slide 140

Slide 140 text

Continuous / Discrete Very Discrete tenderlove

Slide 141

Slide 141 text

Discrete signals are just a list of points

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

Convolution

Slide 144

Slide 144 text

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 * =?

Slide 145

Slide 145 text

Formal Definition

Slide 146

Slide 146 text

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

Slide 147

Slide 147 text

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

Slide 148

Slide 148 text

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

Slide 149

Slide 149 text

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

Slide 150

Slide 150 text

Low Pass Filters

Slide 151

Slide 151 text

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

Slide 152

Slide 152 text

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

Slide 153

Slide 153 text

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

Slide 154

Slide 154 text

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

Slide 155

Slide 155 text

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 *

Slide 156

Slide 156 text

Radar

Slide 157

Slide 157 text

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

Slide 158

Slide 158 text

Does one signal contain the other?

Slide 159

Slide 159 text

received * transmitted Detection -10000 0 10000 20000 30000 40000

Slide 160

Slide 160 text

Gaussian Distribution

Slide 161

Slide 161 text

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

Slide 162

Slide 162 text

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

Slide 163

Slide 163 text

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

Slide 164

Slide 164 text

My Signal

Slide 165

Slide 165 text

R, the hard way

Slide 166

Slide 166 text

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

Slide 167

Slide 167 text

There must be an easier way! tenderlove

Slide 168

Slide 168 text

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

Slide 169

Slide 169 text

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

Slide 170

Slide 170 text

Why?

Slide 171

Slide 171 text

I like learning new languages

Slide 172

Slide 172 text

But I don’t have much time

Slide 173

Slide 173 text

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

Slide 174

Slide 174 text

What are cons, car, and cdr?

Slide 175

Slide 175 text

cons forms a cell L R

Slide 176

Slide 176 text

car returns the left side L R

Slide 177

Slide 177 text

cdr returns the right side L R

Slide 178

Slide 178 text

Only Lambdas?

Slide 179

Slide 179 text

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); }; }

Slide 180

Slide 180 text

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

Slide 181

Slide 181 text

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 >

Slide 182

Slide 182 text

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

Slide 183

Slide 183 text

Tree of Cells 1 2 3 NUL

Slide 184

Slide 184 text

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)); } }

Slide 185

Slide 185 text

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)]$

Slide 186

Slide 186 text

Don’t need loops

Slide 187

Slide 187 text

Don’t need arrays

Slide 188

Slide 188 text

Don’t need hashes

Slide 189

Slide 189 text

Numbers?

Slide 190

Slide 190 text

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

Slide 191

Slide 191 text

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

Slide 192

Slide 192 text

Church Encoding

Slide 193

Slide 193 text

Don’t need Numbers

Slide 194

Slide 194 text

Don’t need Mathematics

Slide 195

Slide 195 text

Logic?

Slide 196

Slide 196 text

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

Slide 197

Slide 197 text

Don’t need booleans

Slide 198

Slide 198 text

Don’t need conditionals

Slide 199

Slide 199 text

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

Slide 200

Slide 200 text

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) }

Slide 201

Slide 201 text

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

Slide 202

Slide 202 text

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)) }

Slide 203

Slide 203 text

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))) }) }

Slide 204

Slide 204 text

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))

Slide 205

Slide 205 text

* = Nice. tenderlove

Slide 206

Slide 206 text

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

Slide 207

Slide 207 text

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

Slide 208

Slide 208 text

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

Slide 209

Slide 209 text

Something I built

Slide 210

Slide 210 text

No content

Slide 211

Slide 211 text

Bathroom Scale

Slide 212

Slide 212 text

msp430

Slide 213

Slide 213 text

Raspberry Pi + Motion Sensor

Slide 214

Slide 214 text

Litter Box

Slide 215

Slide 215 text

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

Slide 216

Slide 216 text

~100g

Slide 217

Slide 217 text

Wrap-Up

Slide 218

Slide 218 text

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