FUNC-damentals

Fundamentals for Functional Programming

slides.com/bgando/knowjs

slides.com/bgando/knowjs

slides.com/bgando/knowjs

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

MONAD

IDEMPOTENT

ARITY

REFERENTIAL TRANSPARENCY

POINTED FUNCTOR

LAMBDA CALCULUS

ENDOMORPHISM

SETOID

COMONAD

POINT FREE STYLE

BEFORE

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

MONAD

IDEMPOTENT

ARITY

REFERENTIAL TRANSPARENCY

POINTED FUNCTOR

LAMBDA CALCULUS

ENDOMORPHISM

SETOID

COMONAD

POINT FREE STYLE

AFTER

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

AFTER

SCOPE

CURRYING

CALLBACKS

HIGHER-ORDER FUNCTIONS

PARAMETERS

LODASH

IMMUTABILITY

SIDE EFFECTS

ES5 + ES6 Syntax

ARGUMENTS

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

Functions - The Basics

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function() { ... };
const _ = {};

_.defaults = () => { ... };
_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });

// → { 'a': 1, 'b': 2 }
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function() { ... };
const _ = {};

_.defaults = () => { ... };
var _ = {
  defaults: function() { ... }
};
const _ = {
  defaults: () => { ... }
};
_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });

// → { 'a': 1, 'b': 2 }
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function() { ... };
const _ = {};

_.defaults = () => { ... };
var _ = {
  defaults: function() { ... }
};
const _ = {
  defaults: () => { ... }
};
const _ = {
  defaults() { ... }
};
_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });

// → { 'a': 1, 'b': 2 }
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function() { ... };
const _ = {};

_.defaults = () => { ... };
_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });

// → { 'a': 1, 'b': 2 }

definition

invocation

arguments

parameters

return statement

side effects

body

name

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function() { ... };
const _ = {};

_.defaults = () => { ... };
_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });

// → { 'a': 1, 'b': 2 }

definition

invocation

arguments

parameters

return statement

side effects

body

name

var _ = {};

_.defaults = function() { ... };
const _ = {};

_.defaults = () => { ... };
_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });

// → { 'a': 1, 'b': 2 }

definition

invocation

arguments

parameters

return statement

side effects

body

name



var nameImprover = function (name, adj) {
  return 'Col ' + name + ' Mc' + adj + ' pants';
};

$('body').hide();

myArr.forEach(function(val){ console.log(val);});

$('button').on('click', function(){ 
  console.log('Don\'t press my buttons!');
});
var _ = {};

_.defaults = function() { ... };
const _ = {};

_.defaults = () => { ... };
_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });

// → { 'a': 1, 'b': 2 }
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object, source) {  




  for (var key in source) {
    var value = object[key];
    if (value === undefined) {
      object[key] = source[key];
    }
  }
  return object;
};
_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });

// → { 'a': 1, 'b': 2 }
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  


  console.log(arguments);

  for (var key in source) {
    var value = object[key];
    if (value === undefined) {
      object[key] = source[key];
    }
  }
  return object;
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });

// → { 'a': 1, 'b': 2 }

arguments keyword

console.log(arguments);
// → [{ 'a': 1 }, { 'a': 3 }, { 'b': 2 }]
// → Arguments [callee: ƒ, ... ƒ]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  


  var sources = arguments.slice(1);

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return object;
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });

// → { 'a': 1, 'b': 2 }

arguments keyword

 var sources = arguments.slice(1);
// → [{ 'a': 3 }, { 'b': 2 }]

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  


  var sources = arguments.slice(1);

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return object;
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });

// → { 'a': 1, 'b': 2 }

arguments keyword

 var sources = arguments.slice(1);
// → [{ 'a': 3 }, { 'b': 2 }]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  


  var sources = arguments.slice(1);

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return object;
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });

// → { 'a': 1, 'b': 2 }

arguments keyword

var args = 
  Array.prototype.slice.call(arguments);

var sources = args.slice(1);
// → [{ 'a': 3 }, { 'b': 2 }]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  

  var args = Array.prototype.slice.call(arguments);
  var sources = args.slice(1);

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return object;
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });

// → { 'a': 1, 'b': 2 }

arguments keyword

var args = 
  Array.prototype.slice.call(arguments);

var sources = args.slice(1);
// → [{ 'a': 3 }, { 'b': 2 }]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  

  var args = Array.prototype.slice.call(arguments);
  var sources = args.slice(1);

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return object;
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });

// → { 'a': 1, 'b': 2 }

arguments keyword

var args = 
  Array.prototype.slice.call(arguments);

var sources = args.slice(1);
// → [{ 'a': 3 }, { 'b': 2 }]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  

  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return object;
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });

// → { 'a': 1, 'b': 2 }
var _ = {};

_.defaults = function(object, ...sources) {  

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return object;
};
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  

  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return object;
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });

// → { 'a': 1, 'b': 2 }
var _ = {};

_.defaults = (object, ...sources) => {  

  sources.forEach(source => {
    for (const key in source) {
      const value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return object;
};
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

Functions - The Basics

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

Functions - The Basics

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function() { ... };
const _ = {};

_.partition = () => { ... };
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item) {
    console.log('heyooo');
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach(item => {
    console.log('heyooo');
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
console.log('heyooo');

// → 'heyooo'
// → 'heyooo'
// → 'heyooo'
// → 'heyooo'
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
console.log('heyooo');

// → 'heyooo'
// → 'heyooo'
// → 'heyooo'
// → 'heyooo'
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item) {
    console.log(arguments);
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach(item => {
    console.log(arguments);
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
console.log(arguments);

// → [1 , 0, list]
// → [2 , 1, list]
// → [3 , 2, list]
// → [4 , 3, list]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
console.log(arguments);

// → [1 , 0, list]
// → [2 , 1, list]
// → [3 , 2, list]
// → [4 , 3, list]
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item) {
    console.log(arguments);
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach(item => {
    console.log(arguments);
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
console.log(arguments);

// → [1 , 0, list]
// → [2 , 1, list]
// → [3 , 2, list]
// → [4 , 3, list]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
console.log(arguments);

// → [1 , 0, list]
// → [2 , 1, list]
// → [3 , 2, list]
// → [4 , 3, list]
console.log('heyooo');

// → 'heyooo'
// → 'heyooo'
// → 'heyooo'
// → 'heyooo'
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item) {
    console.log(arguments);
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach((...args) => {
    console.log(args);
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
console.log(arguments);

// → [1 , 0, list]
// → [2 , 1, list]
// → [3 , 2, list]
// → [4 , 3, list]
console.log(args);

// → [1 , 0, list]
// → [2 , 1, list]
// → [3 , 2, list]
// → [4 , 3, list]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item) {
    console.log(arguments);
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach((...args) => {
    console.log(args);
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
console.log(arguments);

// → [1 , 0, list]
// → [2 , 1, list]
// → [3 , 2, list]
// → [4 , 3, list]
console.log(..args);

// → 1 0 list
// → 2 1 list
// → 3 2 list
// → 4 3 list
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item, index, list) {
    console.log(item);
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach((item, index, list) => {
    console.log(item);
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
console.log(/* ?? */);

// → true
// → false
// → true
// → false
console.log(/* ?? */);

// → true
// → false
// → true
// → false
console.log(/* ?? */);

// → true
// → false
// → true
// → false
console.log(/* ?? */);

// → true
// → false
// → true
// → false
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item, index, list) {
    console.log(cb);
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach((item, index, list) => {
    console.log(cb);
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
console.log(cb);

// → n => n % 2
// → n => n % 2
// → n => n % 2
// → n => n % 2
console.log(cb);

// → ƒ (n) { return n % 2;}
// → ƒ (n) { return n % 2;}
// → ƒ (n) { return n % 2;}
// → ƒ (n) { return n % 2;}
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item, index, list) {
    console.log(cb());
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach((item, index, list) => {
    console.log(cb());
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
console.log(cb());

// → NaN
// → NaN
// → NaN
// → NaN
console.log(cb());

// → NaN
// → NaN
// → NaN
// → NaN
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item, index, list) {
    console.log(cb(item));
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach((item, index, list) => {
    console.log(cb(item));
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
console.log(cb());

// → true
// → false
// → true
// → false
console.log(cb());

// → true
// → false
// → true
// → false
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item, index, list) {
    if(cb(item)) {
      result[0].push(item);
    } else {
      result[1].push(item); 
    }
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach((item, index, list) => {
    if(cb(item)) {
      result[0].push(item);
    } else {
      result[1].push(item); 
    }
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item, index, list) {
    if(cb(item)) {
      result[0].push(item);
    } else {
      result[1].push(item); 
    }
  });
  
  return result;
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach((item, index, list) => {
    if(cb(item)) {
      result[0].push(item);
    } else {
      result[1].push(item); 
    }
  });

  return result;
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item) {
    result[cb(item) ? 0 : 1].push(item);
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach(item => {
    result[cb(item) ? 0 : 1].push(item);
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
function partition(collection, predicate) {
  return reduce(collection, (result, value, key) => (
    result[predicate(value) ? 0 : 1].push(value), result), [[], []])
}
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

IMMUTABLE

CURRIED

ITERATEE

DATA

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

ITERATEE

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

DATA

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item) {
    result[cb(item) ? 0 : 1].push(item);
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach(item => {
    result[cb(item) ? 0 : 1].push(item);
  });
};
_.partition([1, 2, 3, 4], n => n % 2);

// → [[1, 3], [2, 4]]

ITERATEE FIRST - DATA LAST

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(list, cb) {
  var result = [[],[]];

  list.forEach(function(item) {
    result[cb(item) ? 0 : 1].push(item);
  });
};
const _ = {};

_.partition = (list, cb) => {
  const result = [[],[]];

  list.forEach(item => {
    result[cb(item) ? 0 : 1].push(item);
  });
};
_.partition( n => n % 2, [1, 2, 3, 4]);

// → [[1, 3], [2, 4]]

ITERATEE FIRST - DATA LAST

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(cb, list) {
  var result = [[],[]];

  list.forEach(function(item) {
    result[cb(item) ? 0 : 1].push(item);
  });
};
const _ = {};

_.partition = (cb, list) => {
  const result = [[],[]];

  list.forEach(item => {
    result[cb(item) ? 0 : 1].push(item);
  });
};
_.partition( n => n % 2, [1, 2, 3, 4]);

// → [[1, 3], [2, 4]]

ITERATEE FIRST - DATA LAST

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

IMMUTABLE

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.partition = function(cb, list) {
  var result = [[],[]];

  list.forEach(function(item) {
    result[cb(item) ? 0 : 1].push(item);
  });
};
const _ = {};

_.partition = (cb, list) => {
  const result = [[],[]];

  list.forEach(item => {
    result[cb(item) ? 0 : 1].push(item);
  });
};
_.partition( n => n % 2, [1, 2, 3, 4]);

// → [[1, 3], [2, 4]]

IMMUTABLE

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  

  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return object;
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });

// → { 'a': 1, 'b': 2 }
var _ = {};

_.defaults = (object, ...sources) => {  

  sources.forEach(source => {
    for (const key in source) {
      const value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return object;
};

IMMUTABLE

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        obj[key] = source[key];
      }
    }
  });
  return Object.assign({}, obj, object);
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });

// → { 'a': 1, 'b': 2 }
var _ = {};

_.defaults = (object, ...sources) => {  
  const obj = {};
  sources.forEach(source => {
    for (const key in source) {
      const value = object[key];
      if (value === undefined) {
        object[key] = source[key];
      }
    }
  });
  return Object.assign({}, obj, object);
};

IMMUTABLE

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
const defaultA1 = _.defaults({ 'a': 1 });
// →  ƒ () { ... }

defaultA1({ 'a': 3 }, { 'b': 2 })
// → { 'a': 1, 'b': 2 }

defaultA1({ 'z': 3 }, { 'c': 2 })
// → { 'a': 1, 'c': 2, 'z': 3 }

CURRIED

_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });

// → { 'a': 1, 'b': 2 }
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        obj[key] = source[key];
      }
    }
  });
  return Object.assign({}, obj, object);
};
const defaultA1 = _.defaults({ 'a': 1 });
// →  ƒ () { ... }

defaultA1({ 'a': 3 }, { 'b': 2 })
// → { 'a': 1, 'b': 2 }

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  if (!sources.length) {
    return function() {
      console.log('hiii');
    }
  }

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        obj[key] = source[key];
      }
    }
  });
  return Object.assign({}, obj, object);
};
const defaultA1 = _.defaults({ 'a': 1 });
// →  ƒ () { console.log('hiii'); }

defaultA1({ 'a': 3 }, { 'b': 2 })
// → 'hiii'

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  if (!sources.length) {
    return function() {
      console.log(arguments);
    }
  }

  sources.forEach(function(source) {
    for (var key in source) {
      var value = object[key];
      if (value === undefined) {
        obj[key] = source[key];
      }
    }
  });
  return Object.assign({}, obj, object);
};
const defaultA1 = _.defaults({ 'a': 1 });
// →  ƒ () { console.log(arguments); }

defaultA1({ 'a': 3 }, { 'b': 2 })
// → [{ 'a': 3 }, { 'b': 2 }]

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  if (!sources.length) {
    return function() {
     arguments.forEach(function(source) {
      for (var key in source) {
        var value = object[key];
        if (value === undefined) {
          obj[key] = source[key];
        }
      }
    });
    return Object.assign({}, obj, object);
   }
 }

};
const defaultA1 = _.defaults({ 'a': 1 });
// →  ƒ () { ... }

defaultA1({ 'a': 3 }, { 'b': 2 })
// → ??

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  if (!sources.length) {
    return function() {
     arguments.forEach(function(source) {
      for (var key in source) {
        var value = object[key];
        if (value === undefined) {
          obj[key] = source[key];
        }
      }
    });
    return Object.assign({}, obj, object);
   }
 }

};
const defaultA1 = _.defaults({ 'a': 1 });
// →  ƒ () { console.log(arguments); }

defaultA1({ 'a': 3 }, { 'b': 2 })
// → ERROR

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  if (!sources.length) {
    return function() {
      var sources = Array.prototype.slice.call(arguments);
      sources.forEach(function(source) {
        for (var key in source) {
          var value = object[key];
          if (value === undefined) {
            obj[key] = source[key];
          }
        }
      });
    return Object.assign({}, obj, object);
   }
 }

};
const defaultA1 = _.defaults({ 'a': 1 });
// →  ƒ () { console.log(arguments); }

defaultA1({ 'a': 3 }, { 'b': 2 })
// → { 'a': 1, 'b': 2 }

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  if (!sources.length) {
    return function() {
      var sources = Array.prototype.slice.call(arguments);
      sources.forEach(function(source) {
        for (var key in source) {
          var value = object[key];
          if (value === undefined) {
            obj[key] = source[key];
          }
        }
      });
    return Object.assign({}, obj, object);
   }
 }

};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });
// →  ??

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  if (!sources.length) {
    return function() {
      var sources = Array.prototype.slice.call(arguments);
      sources.forEach(function(source) {
        for (var key in source) {
          var value = object[key];
          if (value === undefined) {
            obj[key] = source[key];
          }
        }
      });
    return Object.assign({}, obj, object);
   }
 }

};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });
// →  undefined

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  function defaultFn() {
    var sources = Array.prototype.slice.call(arguments);
    sources.forEach(function(source) {
      for (var key in source) {
        var value = object[key];
        if (value === undefined) {
          obj[key] = source[key];
        }
      }
    });
  return Object.assign({}, obj, object);
 }
 if (!sources.length) {
   return defaultFn;
 } else {
   defaultFn(sources)
 }
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });
// →  ??

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  function defaultFn() {
    var sources = Array.prototype.slice.call(arguments);
    sources.forEach(function(source) {
      for (var key in source) {
        var value = object[key];
        if (value === undefined) {
          obj[key] = source[key];
        }
      }
    });
  return Object.assign({}, obj, object);
 }
 if (!sources.length) {
   return defaultFn;
 } else {
   defaultFn(sources)
 }
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });
// →  undefined

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  function defaultFn() {
    var sources = Array.prototype.slice.call(arguments);
    sources.forEach(function(source) {
      for (var key in source) {
        var value = object[key];
        if (value === undefined) {
          obj[key] = source[key];
        }
      }
    });
  return Object.assign({}, obj, object);
 }
 if (!sources.length) {
   return defaultFn;
 } else {
   return defaultFn(sources);
 }
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });
// →  { 'a': 1, 'b': 2 }

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  function defaultFn() {
    var sources = Array.prototype.slice.call(arguments);
    sources.forEach(function(source) {
      for (var key in source) {
        var value = object[key];
        if (value === undefined) {
          obj[key] = source[key];
        }
      }
    });
  return Object.assign({}, obj, object);
 }

 if (!sources.length) return defaultFn;

 return defaultFn(sources);
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });
// →  { 'a': 1, 'b': 2 }

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
var _ = {};

_.defaults = function(object) {  
  var obj = {};
  var args = 
    Array.prototype.slice.call(arguments);
  var sources = args.slice(1);
  
  function defaultFn() {
    var sources = Array.prototype.slice.call(arguments);
    sources.forEach(function(source) {
      for (var key in source) {
        var value = object[key];
        if (value === undefined) {
          obj[key] = source[key];
        }
      }
   });
   return Object.assign({}, obj, object);
 }
 
 return !sources.length ? defaultFn : defaultFn(sources);
  
};
_.defaults({ 'a': 1 }, { 'a': 3 }, { 'b': 2 });
// →  { 'a': 1, 'b': 2 }

CURRIED

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            
                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

IMMUTABLE

CURRIED

ITERATEE

DATA

                                @BIANCAGANDO
                            
                                KnowJS 2018
                            

Thanks!

                                @BIANCAGANDO
                            
                                KnowJS 2018