Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Everything is composable

176 views

Published on

I'll found many papers and books talking about category theory, but many peoples still don't know how it can help. On this talk I'll help you better understand how math can help us develop a software more composable.

Coder on Beer - Concrete
2018 - São Paulo

Published in: Technology
  • Be the first to comment

Everything is composable

  1. 1. Everything is composable
  2. 2. Hello!I am Victor Igor You can find me at @victorvoid
  3. 3. 1. Programming paradigms A “new” perspective on modeling the flow of your software.
  4. 4. “ In practice, each paradigm comes with its own way of thinking and there are problems for which it is the best approach.
  5. 5. Programming paradigms ◍ Functional programming ◍ Object-oriented programming ◍ Logic programming ◍ Symbolic programming
  6. 6. Composability The essence of software development is composition.
  7. 7. Composability const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('')
  8. 8. Composability const doin_Thangs = str => _.chain(str) .words() .groupBy(s => s.length) .orderBy(x => x.length) .take(2) .flatten() .value()
  9. 9. Composability const reactiveUpInHere = el => fromEvent(el, 'keyup') .map(e => e.target.value) .filter(text => text.length > 2) .throttle(500) .distinctUntilChanged()
  10. 10. Composability (->> (range 1000000000000000000) (filter even?) (map inc) (take 5) (partition 2 1)) ;;=> ((1 3) (3 5) (5 7) (7 9))
  11. 11. Composability player .unitWithinRange(2) .where(UnitIs.Enemy) .where(UnitIs.Tank) .DoDamage(5)
  12. 12. Composability const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('')
  13. 13. Composability const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') ‘Victor and Igor’
  14. 14. Composability const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') ‘victor and igor’
  15. 15. Composability const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') [‘victor’,‘and’,‘igor’]
  16. 16. Composability const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') [‘victor’,‘and’,‘igor’]
  17. 17. Composability const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') [‘igor’,‘and’,‘victor’]
  18. 18. Composability const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') [‘igor’,‘victor’]
  19. 19. Composability const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('') ‘igorvictor’
  20. 20. Composability const doThing = str => { const lower = str.toLowerCase() const words = lower.split(' ') words.reverse() for(let i in words) { words[i] = words[i].trim() } let keepers = [] for(let i in words) { if(words[i].length > 3) { keepers.push(words[i]) } } return keepers.join('') }
  21. 21. Composability const doThing = str => { const lower = str.toLowerCase() const words = lower.split(' ') words.reverse() for(let i in words) { words[i] = words[i].trim() } let keepers = [] for(let i in words) { if(words[i].length > 3) { keepers.push(words[i]) } } return keepers.join('') }
  22. 22. Composability const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('')
  23. 23. Composability
  24. 24. Composability “The major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the system.” Ben Moseley & Peter Marks Out of the Pit 2006
  25. 25. Control flow Composability
  26. 26. Composability Code volume
  27. 27. Composability
  28. 28. Composability
  29. 29. Composability
  30. 30. Composability const dotChainy = str => str .toLowerCase() .split(' ') .map(c => c.trim()) .reverse() .filter(x => x.length > 3) .join('')
  31. 31. Programming !== Math Programming !== Math
  32. 32. Programming !== Math try { return f(x) } catch(e) { console.error(e) }
  33. 33. Programming !== Math if { return f() } else(e) { return y }
  34. 34. Programming !== Math let stuff = [1, 2, 3] stuff = [1, 2]
  35. 35. Programming !== Math let stuff.splice(0, 2) stuff.pop()
  36. 36. Programming !== Math for(let thing in things) { if(thing.amount > 100) keepers.push(thing.name) } for (i = 0; i < cars.length; i++) { text += cars[i] + "<br>"; } while (i < 10) { text += "The number is " + i; i++; }
  37. 37. Assignment Callbacks Loops Side Effects Branching Errors
  38. 38. Programming !== Math Programming !== Math
  39. 39. Programming != Math Programming !== Math
  40. 40. f.g Programming !== Math
  41. 41. f.g = x => f(g(x)) Programming !== Math
  42. 42. str.toUpperCase().trim() Programming !== Math trim(toUpperCase(str))
  43. 43. Category theory
  44. 44. Category Theory What’s category theory?
  45. 45. What’s category theory? Category Theory Categories represent abstraction of other mathematical concepts.
  46. 46. The paradigm shift provoked by Einstein's theory of relativity has brought the realization that there is no single perspective to see the world.
  47. 47. Category Category Theory objects
  48. 48. Category Category Theory objects Arrows or morphisms
  49. 49. Category Category Theory objects Arrows or morphisms Domain dom(f) f
  50. 50. Category Category Theory objects Arrows or morphisms Domain/codomain dom(f) f cod(f)
  51. 51. Category Category Theory objects Arrows or morphisms Domain/codomain dom(f) g cod(f)
  52. 52. Category Category Theory objects Arrows or morphisms Domain/codomain f Composition h
  53. 53. Category Category Theory objects Arrows or morphisms Domain/codomain f Composition h h . f
  54. 54. Category Category Theory objects Arrows or morphisms Domain/codomain Composition Identity
  55. 55. World Wide Web Category Theory
  56. 56. World Wide Web Category Theory objects = webpages Arrows = hyperlinks
  57. 57. World Wide Web Category Theory objects = webpages Arrows = hyperlinks Composition = Links don’t compose Identity
  58. 58. World Wide Web Category Theory objects = nodes Arrows = edges Composition = Edges don’t compose Identity Graphs
  59. 59. Category Theory objects = sets (or types) Arrows = functions Composition = function composition Identity = identity function Programming
  60. 60. Functors Category Theory
  61. 61. Category Theory Functors map between categories Functors
  62. 62. Category Theory A B Category Category Functor F
  63. 63. Category Theory Composition Law F(g ∘ f) = F(g) ∘ F(f) Identity Law F(idA) = idF(A) Functors laws
  64. 64. Category Theory “Hey, I know what can be mapped over. An array can be mapped over — you can map a function over an array!”
  65. 65. Category Theory Identity const f = [1,2,3] f.map(x => x) //[1,2,3]
  66. 66. Category Theory Composition [1,2,3].map(x => f(g(x))) = [1,2,3].map(g).map(f)
  67. 67. Composability const nextCharForNumberString = str => { const trimmed = str.trim() const number = parseInt(trimmed) const nextNumber = number + 1 return String.fromCharCode(nextNumber) } nextCharForNumberString(' 70 ') //'G'
  68. 68. Composability const nextCharForNumberString = str => return [str.trim()] .map(trimmed => new Number(trimmed)) .map(number => number + 1) .map(n => String.fromCharCode(n)) nextCharForNumberString(' 70') //['G']
  69. 69. Category Theory Build your own Functor
  70. 70. Composability const Box = x => ({ map: f => Box(f(x)) })
  71. 71. const Box = x => ({ map: f => Box(f(x)) }) const nextCharForNumberString = str => return Box(str.trim()) .map(trimmed => new Number(trimmed)) .map(number => number + 1) .map(n => String.fromCharCode(n)) nextCharForNumberString(' 70') //Box('G')
  72. 72. const Box = x => ({ map: f => Box(f(x)), fold: f => f(x) }) const nextCharForNumberString = str => return Box(str.trim()) .map(trimmed => new Number(trimmed)) .map(number => number + 1) .fold(n => String.fromCharCode(n)) nextCharForNumberString(' 70') //'G'
  73. 73. Assignment Callbacks Loops Side Effects Branching Errors
  74. 74. Loops
  75. 75. filter map reduce
  76. 76. Assignment Callbacks Loops Side Effects Branching Errors
  77. 77. Callbacks Side effects
  78. 78. Promise(5).then(five => five + 2) //Promise(7) Promise(5).then(five => Promise(five + 2)) //Promise(7) Promise(5).map(five => five + 2)) //Promise(7)
  79. 79. const doThing = () => fs.readFile('file.json', 'utf-8', (err, data) => { if(err) throw err const newdata = data.replace(/8/g, '6') fs.writeFile('file2.json', newdata, (err, _) => { if(err) throw err console.log('success!') } }
  80. 80. const readFile = futurize(fs.readFile) const writeFile = futurize(fs.writefile) const doThing = () => readFile('file.json') .map(data => data.replace('/8/g', '6') .chain(replaced => writeFile('file2.json', replaced))
  81. 81. const readFile = futurize(fs.readFile) const writeFile = futurize(fs.writefile) const doThing = () => readFile('file.json') .map(data => data.replace('/8/g', '6') .chain(replaced => writeFile('file2.json', replaced)) doThing().fork(e => console.log(e), r => console.log('success'))
  82. 82. const lib = username => getTweets(username) .map(tweets => truncateTo130(tweets)) .chain(tweets => writeFile('tweets.json', tweets)) lib('@victorvoid') .chain(f => saveToS3(f)) .fork(e => console.error(e), r => console.log(r))
  83. 83. Assignment Callbacks Loops Side Effects Branching Errors
  84. 84. Errors Branching
  85. 85. Either data Either a b = Left a | Right b
  86. 86. Left('no loaded').fold(() => 'uow, error!', s => s.toUpperCase()) //'uow, error!' Right('loaded').fold(() => 'uow, error!', s => s.toUpperCase()) //'LOADED'
  87. 87. LeftOrRight('no loaded') .fold(() => 'uow, error!', s => s.toUpperCase())
  88. 88. Right(2) .map(x => x + 4) .map(x => x / 2) .fold(() => 'uow, error!', r => r + 1) //4
  89. 89. Left('ignored') .map(x => x + 4) .map(x => x / 2) .fold(() => 'uow, error!', r => r + 1) //'uow, error!'
  90. 90. const getConfig = () => { try { return fs.readFileSync('config.json') } catch (e) { return null } } const getPort = () => { const str = getConfig() if(str) { const parsed = JSON.parse(str) return parsed.port } else (e) { return 3000 } }
  91. 91. const getConfig = () => Either.try(fs.readFileSync)('config.json') const getPort = () => getConfig() .map(JSON.parse) .fold(e => 3000, c => c.port)
  92. 92. const getThing = user => { const address = user.address if(address){ const zip = address.match(/(d{5})$/i) if(zip){ const city = cityByZip(zip) if(city){ return city } else { return 'cant find city' } } } return 'cant find city' }
  93. 93. const getThing = user => fromNullable(user.address) .chain(a => fromNullable(a.match(/(d{5})$/i))) .chain(zip => fromNullable(cityByZip(zip))) .fold(() => 'cant find city', city => city)
  94. 94. Assignment Callbacks Loops Side Effects Branching Errors
  95. 95. React example Component :: a -> JSX
  96. 96. a JSX bf g
  97. 97. a JSX bf g
  98. 98. a JSX fb g
  99. 99. const Comp = g => ({ fold: g, contramap: f => Comp(x => g(f(x))) })
  100. 100. const Comp = g => ({ fold: g, contramap: f => Comp(x => g(f)) }) const heading = str => <h1>You are viewing {str}</h1> const Title = Comp(heading).contramap(s => s.pageName)
  101. 101. const Comp = g => ({ fold: g, contramap: f => Comp(x => g(f)) }) const heading = str => <h1>You are viewing {str}</h1> const Title = Comp(heading).contramap(s => s.pageName) Title.fold({ pageName: 'Home', currUser: {id: '123', name: 'Victor'}}) //<h1>You are viewing Home</h1>
  102. 102. Learn a new language
  103. 103. Fantasy Land Specification
  104. 104. References - Mostly-adequate-guide - Professor-frisby-introduces-composable-functional-javascript - Ramda-fantasy - Functors, Applicatives, And Monads In Pictures - Bartosz Milewski - Category Theory for programmers
  105. 105. Thanks!Any questions? You can find me at @victorvoid & victorvoid.me

×