Project setup

In notebook:
FrontEndMasters Hardcore Functional
Created at:
2017-06-25
Updated:
2017-07-16
Tags:
Functional Programming JavaScript libraries

Part III: The Demo

Congratulations!

You are a pioneer.

These tecniques are new to the javascript ecosystem.

Libraries are evolving

We’ll combine the best ones

• CrossEye / ramda • baconjs / bacon.js -> handles the streams stuff • fantasyland / fantasy-io -> it's a spec to tell you how to name your functions etc. • DrBoolean / pointfree-fantasy -> makes it easier to do pointfree composition stuff • folktale / data.either -> there's a big overlap with ramda, but for now it adds some extra utils

https://github.com/DrBoolean/hardcorejs https://vimeo.com/97575933

His GitHub repo for the demo app. : begriffs/immutube


Starts with Blank State commit

The important things happen in app.js. First shows the interface. It's one empty input box. The goal is that as you type, youtube search results pop up. And you can click on the video to play. It's all client side. He still needs a server to be able to do cross server calls in Chrome (cannot do it if you just open the html file in Chrome).

  
/* global define */
define([
  'jquery'
, 'ramda'
, 'pointfree'
, 'Maybe'
, 'player'
, 'bacon'
], function($, _, P, Maybe, Player, bacon) {
  'use strict';

  // HELPERS ///////////////////////////////////////////////////////////////////////////
  var compose = P.compose;
  var map = P.map;
  var log = function(x) { console.log(x); return x; }
  var fork = _.curry(function(f, future) { return future.fork(log, f); })
  var setHtml = _.curry(function(sel, x) { return $(sel).html(x); });


  // PURE //////////////////////////////////////////////////////////////////////////////

  // IMPURE ////////////////////////////////////////////////////////////////////////////

});

Then start coding

  
/* global define */
define([
...
], function($, _, P, Maybe, Player, bacon) {
  'use strict';
  // **** 6. Add and extend io
  io.extendFn()

  // HELPERS ///////////////////////////////////////////////////////////////////////////
  var compose = P.compose;
  var map = P.map;
  var log = function(x) { console.log(x); return x; }
  var fork = _.curry(function(f, future) { return future.fork(log, f); })
  var setHtml = _.curry(function(sel, x) { return $(sel).html(x); });


  // PURE //////////////////////////////////////////////////////////////////////////////
  // **** 3. change the order of arguments for bacon for currying
  // we want the order of arguments when we curry,
  // so that the first argument should be what we know, 
  // and what we don't know come last
  var listen = _.curry(function (type, elt) {
    return Bacon.fromEventTarget(elt, type)
  })
  
  
  // **** 1. 
  // (attaching an event listener to the DOM is pure)
  // (because it won't run anything here)
  // getDom :: String -> IO Dom
  var getDom = $.toIO()
  // (using jQuery)
  
  // **** 2. then ad click (type) listener/handling
  // keypressStream :: DOM -> EventStream DomEvent
   var keypressStream = listen('keyup')
     
  
  // IMPURE ////////////////////////////////////////////////////////////////////////////
  // **** 4. let's log out
  // compose(map(map(log)), map(keypressStream), getDom('#search'))
  // **** 5. or after some debate use this form instead of above line:
  getDom('#search').map(keypressStream).runIO().onValue
  // **** 7. just get the current value of the input target value
  // (logging out the key event works at this point)
  // cont.. next note

});