Forgotten Funky Functions

Forgotten Funky Functions

Presented at Nordic.js 2015 in Stockholm

7dd731d0c97e334d726f740a710904a9?s=128

Jakob Mattsson

September 10, 2015
Tweet

Transcript

  1. Forgotten funky functions http://jakobm.com @jakobmattsson

  2. None
  3. Startup hedge fund?

  4. None
  5. None
  6. Far from perfect and not for everything* or everyone *

    no, really
  7. None
  8. Smorgasbord

  9. 1 Function => Function 2 Meta-programming 3 There is no

    class
  10. 1 Function => Function

  11. Error handling You just divided by zero, didn’t you?

  12. get('/users/123', function(err, response) { if (err) { cb(err); return; }

    cb(null, response.firstName); });
  13. get('/users/123', p(cb, function(response) { cb(null, response.firstName); }));

  14. var propagate = function(onErr, onSuccess) { return function(err) { if

    (err) { return onErr(err); } else { var slice = Array.prototype.slice; var rest = slice.call(arguments, 1); return onSuccess.apply(this, rest); } }; };
  15. propagate = (onErr, onSucc) -> (err, rest...) -> if err

    then onErr(err) else onSucc(rest...) CoffeeScript ConferenceScript
  16. (function, function) => function

  17. (function, function) => function Need to solve a JavaScript problem?

    Add on one more function!
  18. var once = function(f) { var called = false; var

    result = null; return function() { if (!called) { result = f.apply(this, arguments); called = true; } return result; }; };
  19. var initOnce = once(init); initOnce(); initOnce(); initOnce(); // only called

    once...
  20. var stateful = function(f) { var state = {}; return

    function() { var slice = Array.prototype.slice; var args = slice.call(arguments, 0); return f.apply(this, [state].concat(args)); }; };
  21. var once = stateful(function(state, f) { return function() { if

    (!state.called) { state.result = f.apply(this, arguments); state.called = true; } return state.result; }; });
  22. 1 Function => Function call apply arguments slice bind …and

    closures!
  23. 2 Meta-programming

  24. None
  25. var fullName = function(firstName, lastName) { return firstName + "

    " + lastName; }; fullName('Jakob', ’Mattsson’); // ”Jakob Mattsson”
  26. var fullName = function(firstName, lastName) { return firstName + "

    " + lastName; }; fullName('Jakob', ’Mattsson’); var fullName2 = argsAsObject(fullName); fullName2({ firstName: ’Jakob', lastName: ’Mattsson' });
  27. // foo.com/fullName2?firstName=J&lastName=M funcs[req.path](req.query);

  28. var argNames = function(f) { var reg = /\(([\s\S]*?)\)/; var

    head = reg.exec(f)[1]; var argCands = head.split(/[ ,\n\r\t]+/); var names = argCands.filter(function(x) { return x; }; return names; };
  29. var argsAsObject = function(f) { var names = argNames(f); return

    function(args) { var argValues = names.map(function(name) { return args[name]; }); return f.apply(this, argValues); }; };
  30. var fullName2 = argsAsObject(fullName); fullName2({ firstName: ’Jakob', lastName: ’Mattsson' });

  31. None
  32. fullName = renameArgs(fullName, [ ’first_name’, ’last_name’ ]); var fullName2 =

    argsAsObject(fullName); fullName2({ first_name: ’Jakob', last_name: ’Mattsson' });
  33. var renameArgs = function(__uniq, argNames) { var parts = [

    "(function(", argNames.join(', ') ") { " "return __uniq.apply(this, arguments);" "});" ]; return eval(parts.join('')); };
  34. None
  35. fullName2({ firstName: 'Jakob', lastName: 'Mattsson' }); var fullName = spreadArguments(fullName2,

    [ 'firstName', 'lastName' ]); fullName('Jakob', 'Mattsson'); // => 'Jakob Mattsson' Challenge!
  36. 2 Meta-programming eval Function.toString()

  37. 3 There is no class

  38. new MyConstructor MyConstructor.prototype … and what about types?? Original JavaScript

  39. class constructor extend(s) super CoffeeScript and ECMAScript 6

  40. Everyone forgot Object.create

  41. var Animal = { greet: function() { return this.speak() +

    ” says ” + this.name; } }; var Dog = Object.create(Animal); Dog.speak = function() { return ”woof”; }; var zelda = Object.create(Dog); zelda.name = ”zelda”; console.log(zelda.greet());
  42. But overloading?!

  43. var Animal = { greet: function() { return this.speak() +

    " says " + this.name; } }; var Dog = createAndInit(Animal, { speak: function(superSpeak) { return "woof"; }, greet: function(superGreet) { return superGreet() + ", who is a dog"; } });
  44. var createAndInit = function(source, props){ var slice = Array.prototype.slice; var

    newObj = Object.create(source); Object.keys(props).forEach(function(propName){ newObj[propName] = function(){ var zup = source[propName]; var boundZuper = zup ? zup(this) : null; var newFunc = props[propName]; var args = slice.call(arguments, 0); var allArgs = [boundZuper].concat(args); return newFunc.apply(this, allArgs); }; }); return newObj; };
  45. So what is Object.create really?

  46. Object.create = function(x) { function F() {} F.prototype = x;

    return new F(); }; new MyConstructor MyConstructor.prototype
  47. "I have been writing JavaScript for 14 years now (...).

    The super idea is fairly important in the classical pattern, but it appears to be unnecessary in the prototypal and functional patterns. I now see my early attempts to support the classical model in JavaScript as a mistake.” http://www.crockford.com/javascript/inheritance.html
  48. 3 There is no class Object.create

  49. None
  50. Forgotten funky functions http://jakobm.com @jakobmattsson