Slide 1

Slide 1 text

The Art of Functional Programming @AnjanaVakil

Slide 2

Slide 2 text

functional programming is beautiful!

Slide 3

Slide 3 text

functional programming is easy to predict

Slide 4

Slide 4 text

functional programming is easy to test

Slide 5

Slide 5 text

functional programming is easy to debug

Slide 6

Slide 6 text

functional programming is easy to love

Slide 7

Slide 7 text

functional programming is easy to fear?

Slide 8

Slide 8 text

functional programming is easy (enough) to understand

Slide 9

Slide 9 text

“Learning Functional Programming with JS” youtu.be/e-5obm1G_FY

Slide 10

Slide 10 text

frontendmasters.com/courses/functional-first-steps

Slide 11

Slide 11 text

functional programming is programming with functions

Slide 12

Slide 12 text

functional programming is programming with pure functions

Slide 13

Slide 13 text

a pure function is input => output (width, height) => width/height

Slide 14

Slide 14 text

a pure function is deterministic, stateless same input => same output

Slide 15

Slide 15 text

a pure function is free of side effects console.log() document.append() element.getAttribute()

Slide 16

Slide 16 text

functional programming is pretty useless?

Slide 17

Slide 17 text

how does FP work in the real world?

Slide 18

Slide 18 text

let’s make functional art!

Slide 19

Slide 19 text

generative art usually needs ● Side effects ● Repetition ● State ● Randomness

Slide 20

Slide 20 text

how does FP handle side effects?

Slide 21

Slide 21 text

imperative shell pure functional core deterministic in here safe & sound side effects out here

Slide 22

Slide 22 text

function impureSetSVGContents(contents) { const art = document.getElementById("art"); art.innerHTML = contents; return art; } impureSetSVGContents(pureGetArt(params));

Slide 23

Slide 23 text

let’s make patterns!

Slide 24

Slide 24 text

how does FP handle repetition?

Slide 25

Slide 25 text

imperative: iteration functional: recursion

Slide 26

Slide 26 text

“Recursion, Iteration, and JavaScript: A Love Story" youtu.be/FmiQr4nfoPQ

Slide 27

Slide 27 text

function getPattern(color1, color2, width) { const thisTile = ``; if (width <= 20) { return `${thisTile}`; } return `${thisTile} ${getPattern(color2, color1, width * hyp)} `; } getPattern("limegreen", "rebeccapurple", 100) base case recursive case

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

function getTiles(width, height, cols, rows, makeTile, data) { const [colWidth, rowHeight] = [width / cols, height / rows]; const [thisTile, newData] = makeTile(colWidth, rowHeight, data); return `${thisTile} ${cols > 1 ? // rest of this row to the right of this tile ` ${getTiles(width-colWidth, rowHeight, cols-1, 1, makeTile, newData)} ` : ``} ${rows > 1 ? // rows below this one ` ${getTiles(width, height-rowHeight, cols, rows-1, makeTile, newData)} ` : ``}`;} function makeBasicTile(width, height, { color }) { return [ ``, { color } ];} getTiles(100, 100, 5, 5, basicTile, { color: "orange" }) base recursive recursive

Slide 33

Slide 33 text

how does FP handle state?

Slide 34

Slide 34 text

treat state like data [input, oldState] => [output, newState]

Slide 35

Slide 35 text

function makeCheckerTile(width, height, { colors, colorIndex }) { return [ ``, { colors, colorIndex: (colorIndex + 1) % colors.length } ]; } getTiles(100, 100, 5, 5, makeCheckerTile, { colors: ["orange", "hotPink"], colorIndex: 0 })

Slide 36

Slide 36 text

let’s make functional fashion! design: palmettadesign.hu

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

function makeTiledTile(width, height, data) { const split = 0.7; const [sWidth, sHeight] = [width*split, height*split]; const newData = {...data, colorIndex: data.n % 2 === 0 ? data.colorIndex : (data.colorIndex + 1) % data.colors.length }; const big = getTiles(sWidth, sHeight, …, makeCheckerTile, data); const narrow = getTiles(width-sWidth, sHeight, …, makeCheckerTile, newData); const wide = getTiles(sWidth, height-sHeight, …, makeCheckerTile, newData); const small = getTiles(width-sWidth, height-sHeight, …, makeCheckerTile, data); return [ `${big} ${narrow} ${wide} ${small}`, data ];} rotate(getTiles(200, 200, 8, 8, tiledTile, { colors: ["orange", "hotpink"], colorIndex: 0, n: 5 }))

Slide 44

Slide 44 text

let’s get irregular!

Slide 45

Slide 45 text

how does FP handle randomness?

Slide 46

Slide 46 text

it doesn’t! (nor does any computation)

Slide 47

Slide 47 text

but we can get pseudo-randomness

Slide 48

Slide 48 text

zoomed out zoomed in simplex noise

Slide 49

Slide 49 text

const SimplexNoise = require("simplex-noise@2.4") function impureGetNoiseField(seed) { return new SimplexNoise(seed); } const myNoise = impureGetNoiseField("hello noise!"); myNoise.noise2D(50, 50); // 0.38978764467539995 const otherNoise = impureGetNoiseField("other noise!"); otherNoise.noise2D(50,50); // -0.10783404678637644 const sameNoise = impureGetNoiseField("hello noise!"); sameNoise.noise2D(50,50); // 0.38978764467539995

Slide 50

Slide 50 text

function makeRandomTile(width, height, { colors, noiseField, tileIndex }) { const noiseHere = noiseField.noise2D(tileIndex * width, tileIndex * height); const colorIndex = Math.floor(Math.abs(noiseHere * 50)) % colors.length; return [ ``, { noiseField, colors, tileIndex: tileIndex + 1 } ]; } getTiles(100, 100, 30, 30, makeRandomTile, { colors: ["orange", "hotpink", "purple"], noiseField: myNoise, tileIndex: 0 })

Slide 51

Slide 51 text

function makeClockTile(width, height, data) { const { colors, tileIndex, noiseField } = data; const noiseHere = noiseField.noise2D(tileIndex * width, tileIndex * height); const degree = 45 * (noiseHere * 4); const colorIndex = tileIndex % colors.length; return [ ` `, { ...data, tileIndex: tileIndex + 1} ]; } getTiles(100, 100, 5, 5, clockTile, { noiseField: myNoise, colors: ["yellow", "limegreen", "hotpink", "orange"], tileIndex: 0 })

Slide 52

Slide 52 text

look at all we made! ● Side effects ● Repetition ● “State” ● “Randomness”

Slide 53

Slide 53 text

Thanks! @AnjanaVakil observablehq.com/@anjana slide design: slidescarnival.com