Transducer

C4ce16f549c450f4759eb37f5d5d1a63?s=47 othree
October 03, 2015

 Transducer

Explain transducer in JS code snippets

C4ce16f549c450f4759eb37f5d5d1a63?s=128

othree

October 03, 2015
Tweet

Transcript

  1. 7UDQVGXFHU

  2. :DUQLQJ Ŏ /RWVRIFRGHVQLSSHWV Ŏ /RWVRIPDWKHTXDWLRQ

  3. Ŏ &RPSRVDEOHFROOHFWLRQGDWDRSHUDWLRQV

  4. 2XWOLQH Ŏ )XQFWLRQFRPSRVLWLRQ Ŏ 0DSUHGXFH Ŏ &ROOHFWLRQGDWDRSHUDWLRQV Ŏ 7UDQVGXFHU

  5. )XQFWLRQ&RPSRVLWLRQ

  6. function incOne(input) { return input + 1; } function multTwo(input)

    { return input * 2; }
  7. function incOneMultTwo(input) { return (input + 1) * 2; }

  8. function incOneMultTwo(input) { return multTwo(incOne(input)); }

  9. z = f(y) y = g ( x ) z

    = f ( g ( x ))
  10. x g ! y f ! z

  11. z = h ( x ) h = f g

  12. h = f g ¯ h = g f

  13. 7UDQVIRUPDWLRQ Ŏ +DYLQJWKHVDPHGRPDLQDQGFRGRPDLQ Ŏ ,QSXWDQGRXWSXWEHWKHVDPHW\SH

  14. f : X 7! X g : X 7! X

  15. whatever 7! whatever

  16. function multTwoIncOne(input) { return incOne(multTwo(input)); }

  17. var incOneMultTwo = compose(incOne, multTwo);

  18. function compose(f, g) { return function (input) { return f(g(input));

    }; }
  19. 3URV Ŏ 6PDOOIXQFWLRQV Ŏ (DV\WRZULWH Ŏ (DV\WRWHVW Ŏ &RGHUHXVH

  20. 0DS5HGXFH

  21. 0DS Ŏ $SSO\WUDQVIRUPDWLRQWRDOOHOHPHQWVRIJLYHQ FROOHFWLRQ

  22. map ( transform, coll ) ! coll 0

  23. [1,2,3,4].map(function (input) { return input + 1; }); // =>

    [2,3,4,5]
  24. [1,2,3,4].map(incOne);
 // => [2,3,4,5]

  25. [1,2,3,4].map(incOneMultTwo);
 // => [4,6,8,10]

  26. 5HGXFH Ŏ 5HGXFHDFROOHFWLRQWRDVLQJOHYDOXH

  27. reduce ( reducing, coll ) ! whatever

  28. [1,2,3,4].reduce(function(result, value) { return result + value; }, 0); //

    10
  29. [1,2,3,4].reduce(function(result, value) { return result * value; }, 1); //

    24
  30. [1,2,3,4].reduce(function(result, value) { return result.push(value); }, []); // [1, 2,

    3, 4]
  31. 5HGXFLQJ)XQFWLRQ Ŏ )XQFWLRQSDVVHGWRUHGXFH Ŏ +RZWRDFFXPXODWHYDOXHV Ŏ 5HGXFHWRFROOHFWLRQLVSRVVLEOH

  32. whatever, input 7! whatever

  33. [1, 2, 3, 4].reduce(function(result, value) { return result + value;

    }, 0); // 10 whatever whatever input
  34. Ŏ 5HGXFLQJIXQFWLRQLVQRWFRPSRVDEOH

  35. &ROOHFWLRQ2SHUDWLRQV

  36. )LOWHU Ŏ 5HWXUQQHZFROOHFWLRQZLWKZDQWHGHOHPHQW RQO\XVHSUHGLFDWHIXQFWLRQ

  37. filter ( predicate, coll ) ! coll 0

  38. [1,2,3,4].filter(function (input) { return (input % 2 == 0); });

    // [2, 4]
  39. function even (input) { return (input % 2 == 0);

    } [1,2,3,4].filter(even); // [2, 4]
  40. Ŏ 5HGXFLQJIXQFWLRQFDQUHWXUQDQHZFROOHFWLRQ

  41. Ŏ %RWKPDSDQGƉOWHUFDQXVHUHGXFHWRLPSOHPHQW

  42. [1,2,3,4].map(function (input) { return input + 1; }); // =>

    [2,3,4,5]
  43. [1,2,3,4].reduce(function (result, input) { return result.push(input + 1); }, []);

    // [2,3,4,5]
  44. [1,2,3,4].filter(function (input) { return (input % 2 == 0); },

    []); // [2,4]
  45. [1,2,3,4].reduce(function (result, input) { return ( input % 2 ==

    0 ? concat(result, input) : result ); }, []) // => [2, 4]
  46. PDS UHGXFH ƉOWHU GHGXSH WDNH UHSODFH VRUW FDW SDUWLWLRQ

  47. Ŏ (YHU\FROOHFWLRQRSHUDWLRQFDQXVHUHGXFHWR LPSOHPHQW Ŏ 7KHQXPEHURIHOHPHQWVLQFROOHFWLRQLVPXWDEOH

  48. 7UDQVGXFHU

  49. Ŏ 7UDQVGXFHUFRPHVIURP&ORMXUH

  50. Ŏ 7UDQVGXFHULVDUHGXFLQJIXQFWLRQWUDQVIRUP IXQFWLRQ Ŏ 7UDQVIRUPRQHUHGXFLQJIXQFWLRQWRDQRWKHU UHGXFLQJIXQFWLRQ

  51. http://clojure.org/transducers (whatever, input 7! whatever) 7! (whatever, input 7! whatever)

  52. Ŏ ,QSXWUHGXFLQJIXQFWLRQ Ŏ 2XWSXWUHGXFLQJIXQFWLRQ Ŏ &RPSRVDEOH

  53. T : transducer R : reducing function Rmap Tfilter !

    Rmap,filter
  54. map reducing function map transducer filter reducing function filter transducer

    take reducing function take transducer replace reducing function replace transducer
  55. var c = chan( 1, // buffer size compose( //

    Only events with even x & y filtering(function (e) { return ( even(e.pageX) && even(e.pageY) ); }), // e -> [type, x, y] mapping(function (e) { return [e.type, e.pageX, e.pageY]; }) ) );
  56. var c = chan( 1, // buffer size compose( //

    Only events with page x & y filtering(function (e) { return ( even(e.pageX) && even(e.pageY) ); }), // e -> [type, x, y] mapping(function (e) { return [e.type, e.pageX, e.pageY]; }) ) );
  57. var c = chan( 1, // buffer size compose( //

    Only events with page x & y filtering(function (e) { return ( even(e.pageX) && even(e.pageY) ); }), // e -> [type, x, y] mapping(function (e) { return [e.type, e.pageX, e.pageY]; }) ) );
  58. var c = chan( 1, // buffer size compose( //

    Only events with page x & y filtering(function (e) { return ( even(e.pageX) && even(e.pageY) ); }), // e -> [type, x, y] mapping(function (e) { return [e.type, e.pageX, e.pageY]; }) ) );
  59. var c = chan( 1, // buffer size compose( //

    Only events with page x & y filtering(function (e) { return ( even(e.pageX) && even(e.pageY) ); }), // e -> [type, x, y] mapping(function (e) { return [e.type, e.pageX, e.pageY]; }) ) ); transducer transducer
  60. var c = chan( 1, // buffer size compose( //

    Only events with page x & y filtering(function (e) { return ( even(e.pageX) && even(e.pageY) ); }), // e -> [type, x, y] mapping(function (e) { return [e.type, e.pageX, e.pageY]; }) ) ); filter transducer constructor map transducer constructor
  61. var c = chan( 1, // buffer size compose( //

    Only events with page x & y filtering(function (e) { return ( even(e.pageX) && even(e.pageY) ); }), // e -> [type, x, y] mapping(function (e) { return [e.type, e.pageX, e.pageY]; }) ) ); filter predicate map transform
  62. x g ! y f ! z

  63. x g ! y f ! z transducer reducing function

  64. var c = chan( 1, // buffer size compose( //

    Only events with page x & y filtering(function (e) { return ( even(e.pageX) && even(e.pageY) ); }), // e -> [type, x, y] mapping(function (e) { return [e.type, e.pageX, e.pageY]; }) ) ); f
  65. var c = chan( 1, // buffer size compose( //

    Only events with even x & y filtering(function (e) { return ( even(e.pageX) && even(e.pageY) ); }), // e -> [type, x, y] mapping(function (e) { return [e.type, e.pageX, e.pageY]; }) ) ); g
  66. x h ! z h = f g

  67. var c = chan( 1, // buffer size // Only

    events with even x & y // And transform format to [type, x, y] compose( // Only events with even x & y filtering(function (e) { return ( even(e.pageX) && even(e.pageY) ); }), // e -> [type, x, y] mapping(function (e) { return [e.type, e.pageX, e.pageY]; }) ) ); h
  68. x g ! y f ! z

  69. x g ! y f ! z coll 0 =

    reduce ( z, coll )
  70. x g ! y f ! z x g !

    y f ! z
  71. :KDWLVx

  72. Ŏ xLVODVWUHGXFLQJIXQFWLRQEXLOGWKHQHZFROOHFWLRQ IURPHOHPHQWV

  73. function (result, value) { return result.push(value); }

  74. function (result, value) { return result.append(value); }

  75. function (result, value) { return result[value[0]] = value[1]; }

  76. function (result, value) { return result.put(value); }

  77. Ŏ 7UDQVGXFHUGRQŇWNQRZEXLOGIXQFWLRQIRUHYHU\ FROOHFWLRQW\SHGDWD Ŏ 2QO\WKHGDWDW\SHNQRZVKRZWREXLOGLWVVHOI

  78. &ROO5HGXFH3URWRFRO Ŏ )RUFROOHFWLRQGDWDIURP&ORMXUH Ŏ 3URYLGHPHWKRGWRLWHUDWHDQGEXLOGFROOHFWLRQ
 DQGLQLWLDOYDOXH perform reduce , CollReduce

    x
  79. var receipt = compose( mapping(incOne), filtering(even) ); var reduceToArray =

    function (result, input) { return result.push(input); } [1,2,3,4].reduce( receipt(reduceToArray) , []); // [2, 4]
  80. var receipt = compose( mapping(incOne), filtering(even) ); var reduceToArray =

    function (result, input) { return result.push(input); } [1,2,3,4].reduce( receipt(reduceToArray) , []); // [2, 4] x h z h ( x )
  81. var receipt = compose( mapping(incOne), filtering(even) ); var reduceToArray =

    function (result, input) { return result.push(input); } [1, 2, 3, 4].reduce( receipt(reduceToArray) , []); // [2, 4] CollReduce initial value iterate
  82. Ŏ &ORMXUHKDYHQDWLYH&ROO5HGXFHSURWRFRO Ŏ 2WKHUODQJXDJHQHHGWRLPSOHPHQWLWDQGFXVWRP UHGXFH

  83. 5HGXFLQJ)XQFWLRQ 7UDQVIRUP

  84. +RZ

  85. 0DS coll.map(transform);

  86. 0DSE\5HGXFH coll.reduce(function (result, input) { return concat(result, input + 1);

    }, []) CollReduce map transform
  87. %XLOGIURP&ROO5HGXFH 3URWRFRO

  88. function (result, input) { return concat(result, input + 1); }

  89. 'HFRXSOH&ROO5HGXFH

  90. ,QF2QH7UDQVGXFHU function (reducing) { return function (result, input) { return

    reducing(result, input + 1); }; } map transform CollReduce
  91. 'HFRXSOH7UDQVIRUP

  92. 0DS7UDQVGXFHU&RQVWUXFWRU function mapping(transform) { return function (reducing) { return function

    (result, input) { return reducing(result, transform(input)); }; }; }
  93. function mapping(transform) { return function (reducing) { return function (result,

    input) { return reducing(result, transform(input)); }; }; } transducer constructor
  94. function mapping(transform) { return function (reducing) { return function (result,

    input) { return reducing(result, transform(input)); }; }; } transducer x g ! y f ! z g
  95. function mapping(transform) { return function (reducing) { return function (result,

    input) { return reducing(result, transform(input)); }; }; } reducing function
  96. function mapping(transform) { return function (reducing) { return function (result,

    input) { return reducing(result, transform(input)); }; }; } whatever
  97. function mapping(transform) { return function (reducing) { return function (result,

    input) { return reducing(result, transform(input)); }; }; } CollReduce initial value map transform x y x g ! y f ! z x g ! y f ! z
  98. )LOWHU7UDQVGXFHU&RQVWUXFWRU function filtering(predicate) { return function (reducing) { return function

    (result, input) { return ( predicate(input) ? reducing(result, input) : result ); }; }; }
  99. 7DNH7UDQVGXFHU&RQVWUXFWRU function taking(n) { return function (reducing) { return function

    (result, input) { if (n > 0) { n--; return reducing(result, input); } else { return result; } }; }; }
  100. 'URS7UDQVGXFHU&RQVWUXFWRU function dropping(n) { return function (reducing) { return function

    (result, input) { if (n > 0) { n--; return result; } else { return reducing(result, input); } }; }; }
  101. var c = chan( 1, // buffer size compose( //

    Only events with even x & y filtering(function (e) { return ( even(e.pageX) && even(e.pageY) ); }), // e -> [type, x, y] mapping(function (e) { return [e.type, e.pageX, e.pageY]; }) ) );
  102. 7UDQVGXFHUMV

  103. https://github.com/jlongster/transducers.js

  104. Ŏ ,PSOHPHQWLWVRZQ&ROO5HGXFHSURWRFRO Ŏ ,PSOHPHQWUHGXFHEDVHGRQ&ORMXUHŇVGHVLJQ Ŏ :RUNZLWKMVFVS

  105. var map = t.map, filter = t.filter, comp = t.comp,

    into = t.into, apush = function(arr, x) { arr.push(x); return arr; }, var inc = function(n) { return n + 1; }; var isEven = function(n) { return n % 2 == 0; }; var xf = comp(map(inc), filter(isEven)); into([], xf, [0,1,2,3,4]); // [2,4] transduce(xf, apush, 0, [0,1,2,3,4]); // [2,4]
  106. var map = t.map, filter = t.filter, comp = t.comp,

    into = t.into, apush = function(arr, x) { arr.push(x); return var inc = function(n) { return n + 1; }; var isEven = function(n) { return n % 2 == 0; }; var xf = comp(map(inc), filter(isEven)); into([], xf, [0,1,2,3,4]); // [2,4] transduce(xf, apush, 0, [0,1,2,3,4]); // [2,4] CollReduce transducer initial value coll
  107. &ORMXUH7UDQVGXFHU&RQVWUXFWRU (fn [xf] (fn ([] ...) ([result] ...) ([result input]

    ...)))
  108. [] Init: return initial value [result] Completion: some reduce operation

    require this step [result, input] Step: reducing function to build collection
  109. http://jlongster.com/Transducers.js--A-JavaScript-Library-for-Transformation-of-Data

  110. http://phuu.net/2014/08/31/csp-and-transducers.html

  111. Q?