Forgotten Funky Functions

Forgotten Funky Functions

Given at JsDay in Verona 2016-05-11

7dd731d0c97e334d726f740a710904a9?s=128

Jakob Mattsson

May 11, 2016
Tweet

Transcript

  1. Forgotten funky functions @jakobmattsson

  2. None
  3. None
  4. ALL CHARACTERS AND EVENTS IN THIS SHOW-- EVEN THOSE BASED

    ON REAL PEOPLE--ARE ENTIRELY FICTIONAL. ALL CELEBERTY VOICES ARE IMPERSONATED.....POORLY. THE FOLLOWING PROGRAM CONTAINS COARSE LANGUAGE AND DUE TO ITS CONTENT IT SHOULD NOT BE VIEWED BE ANYONE
  5. Far from perfect and not for everything* or everyone *

    no, really
  6. None
  7. Smorgasbord

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

    class
  9. 1 Function => Function

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

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

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

  13. 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); } }; };
  14. propagate = (onErr, onSucc) -> (err, rest...) -> if err

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

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

    Add on one more function!
  17. var initOnce = once(init); initOnce(); initOnce(); initOnce(); // ”init” is

    only called once...
  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(); // ”init” is

    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. var names = argNames(fullName); // [’firstName’, ’lastName']

  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. var fullNameSnake = renameArgs(fullName, [ ’first_name’, ’last_name’ ]); var fullName2

    = argsAsObject(fullNameSnake); fullName2({ first_name: ’Jakob', last_name: ’Mattsson' });
  33. Don’t try this at 127.0.0.1

  34. var renameArgs = function(__uniq, argNames) { var parts = [

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

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

  38. 3 There is no class

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

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

  41. Everyone forgot Object.create

  42. 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());
  43. But overloading?!

  44. 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"; } });
  45. 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; };
  46. So what is Object.create really?

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

    return new F(); }; new MyConstructor MyConstructor.prototype
  48. "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
  49. 3 There is no class Object.create

  50. None
  51. Forgotten funky functions @jakobmattsson