Monday, March 16, 2020

What The Hell Is Babel?

INTRODUCTION

This article is simply an expansion on the excellent article posted here

https://medium.com/@bluepnume/jsx-is-a-stellar-invention-even-with-react-out-of-the-picture-c597187134b7

The reason I created this article is because I wanted to actually try what this article shows but it took me a few minutes to get that code setup and working (and the posted code actually breaks) so I figured this might save some other folks some time, plus I wanted to have a reference so I could repeat this process in the future.

JSX is a templating language which is typically used by a transpiler called 'Babel' to produce React.js code. JSX syntax is very much like Javascript syntax with inline styles though even the styles can be further broken out into separate CSS type files (which is what you tend to do when you use 'React Styled Components'). This article just concentrates on Babel (with some minor 'node' thrown in for ease of use) but you should be aware that in most cases folks also use something called webpack to produce their final product. webpack automates what we manually do near the end of this article when we manually copy files and paste them into our html file to create a browser renderable file. Also note this example uses babel-cli which means Babel from the command line, though you could also simply include Babel as a '<script>' tag in your html file and that would cause transpilation to occur at run time versus at build time. I specifically use babel-cli because I want to see what Babel actually produces and how it converts ES6 to plain vanilla ES4. I also override the React output function and provide a vanilla Javascript output function to aid in this process. 

If you are new to all of this you might struggle a bit with this post. Basically, ES4 is old style Javascript and ES6 is a newer version of Javascript and ES6 is not backwards compatible with ES4. To fix this Babel comes into the picture. You can think of Babel as a tool to convert new Javascript (ES6) to old style Javascript (ES4) although it is capable of doing far more than this. From a high level this solves most browser compatibility issues, though as I say, this is just one benefit of using Babel

What this article (and the original one it is based on) is trying to show is that even though Babel appears to be tightly coupled to React.js, it isn't. JSX is simply a templating language which can be transpiled by Babel into nearly anything. The fact that Babel is almost exclusively used to transpile JSX to React.js or Typescript is simply a reflection of how it is used. It does not have to produce either of these two target languages and so in this article I (as the original author also did) will show you exactly what that means by simply using Babel to transpile ES6 to ES4. Worth understanding if you ever have a bug you suspect was due to the conversion process. BTW you should read the original article first and if it makes sense to you and you can get it running from that article, then you really don't need to read any further. Its just that it took me a while to actually be able to put up a simple web page that used Babel to transpile ES6 to working Javascript following that example so I felt I needed a working example for future reference. Note the only reason that the original article doesn't work is it uses 'null' in two places. If you simply replace these with {id:"someId"} the example will build fine. You would still need to integrate it with your html file to get it to run in your browser and we will do this later in this article.

THE SETUP


So first, we need to have node.js installed and working on our computer. Open up a shell/command line terminal on your computer and type 

node --version

If this doesn't show you a version then install node by following the instructions shown here for Windows 

https://www.guru99.com/download-install-node-js.html

or here for Mac

https://www.webucator.com/how-to/how-install-nodejs-on-mac.cfm

Assuming all worked as expected (IE 'node --version' actually shows a version) we will now create our basic project. To do this create a directory called 'jsx_pragma'. I am using a Mac and I created this directory on my desktop so you will need to adjust accordingly. Using your GUI you could just right click on your desktop and create a new folder.

Once you have created your 'jsx_pragma' directory (some folks call it a folder) open a terminal and navigate into it ('cd ~Desktop/jsx_pragma' should work) and then create a file called package.json. Paste this into it.

{
  "name": "jsx_pragma",
  "version": "1.0.0",
  "description": "test jsx pragma",
  "main": "RenderDom.js",
  "dependencies": {
    "babel-cli": "^6.26.0"
  },
  "devDependencies": {
    "babel-preset-env": "^1.7.0"
  },
  "scripts": {
    "build": "babel src -d dist"
  },
  "author": "",
  "license": "ISC"
}

Now simply type this on the command line 

npm install

This will download all the stuff you need to actually build this project. It will figure all this out from the dependencies we put in our 'package.json' file. This is because 'npm' stands for node package manager which is part of node and this is what npm does for a living. Specifically you should see a directory called 'node_modules' and a file named 'package-lock.json' in this directory alongside the 'package.json' file we just created. 

We are not going to go too much in detail about what our 'package.json' file contains except for one key section. If you look in the 'package.json' file we created you will see this 

  "scripts": {
    "build": "babel src -d dist"
  },

Which basically defines a script we will ask npm to execute later. In our case, this script is called 'build'. It also tells npm what to run when we say 'npm run build' which in our case is babel. Additionally we are telling babel to look for input files in the directory 'src' and to place output files in the directory named 'dist'. This is pretty standard stuff but first we should actually create those two directories. You can do this however you want, just make sure these two directories exist in our 'jsx_pragma' directory. For example, you could use your GUI (right click in the 'jsx_pragma' folder and create a new folder) or you could execute these commands from the command line in the 'jsx_pragma' folder

mkdir src
mkdir dist

Once you have done this your 'jsx_pragma' folder should look something like this 

/dist
/src
/node_modules
package-lock.json
package.json

Where dist, src and node_modules are directories and package-lock.json and package.json are files. 

We are almost ready. We simply need to create two source files which are actually our project and we will be done. Create a file named 'RenderDom.js' and put it in the 'src' directory 

RenderDom.js
-------------
let renderDom = (name, props, ...children) => {
  let el = document.createElement(name);
  for (let [key, val] of Object.entries(props)){
    el.setAttribute(key, val);
  }
  for (let child of children){
    if (typeof child === 'string'){
      el.appendChild(document.createTextNode(child));
    } else {
      el.appendChild(child);
    }
  }
  return el;
}

Next create a file named 'test_render.js' and also put it in the 'src' directory 

test_render.js
--------------
/* @jsx renderDom */

function renderLogin(){
  return renderDom("section", {id:"secId"}, 
    renderDom("input", {type:"email", value:""}),
    renderDom("input", {type:"password", value:""}),
    renderDom("button", {id:"butId"}, "Log In")
  );
}

Note those are not really JSX but rather standard Javascript (thanks to Scott for pointing that out) but since we are really interested in Babel we won't worry about that. Now we can run the following command and we should get two files in our 'dist' folder.

npm run build

We are almost done. The reason I say almost is for some reason the babel presets don't get set automatically. I have no idea why. I mean they are in our 'package.json' file but still, they don't work. To fix this you could alter the babel command line in the 'package.json' file to include them but I prefer to simply create a .babelrc file and put them in there. So, create a new file in the 'jsx_pragma' directory and call it '.babelrc' and stick this in there (NOTE don't forget the leading dot when you create .babelrc !)

{
  "presets" : [ "/Users/kensmith/Desktop/jsx_pragma/node_modules/babel-preset-env" ]
}

Two things to note. First you will need to change this line to point to where YOUR 'jsx_pragma' folder is located. In the example above it is located at '/Users/kensmith/Desktop/' on my machine. I am assuming yours is not in a directory called '/Users/kensmith'. Also, you must use an absolute path. Do not try to take a shortcut and use a relative path. Specifically, this works 

/Users/kensmith/Desktop/jsx_pragma/node_modules/babel-preset-env

This does not work

jsx_pragma/node_modules/babel-preset-env

I believe this is a babel6 limitation. 

Once you have created your .babelrc file and placed it in the proper directory and modified the absolute path in that file to point to YOUR 'jsx_pragma' directory location you should be able to run 

npm run build

Remember, our output will be located in our 'dist' directory and we will need to put it in a html file to actually see it in action in our browser. You could run it just using node but that's no fun, so create the following file and put it on your desktop (or somewhere you can easily find) and call it test.html. 

test.html
--------
<html>
  <head>
  </head>
  <body>
    <div id="ruut" name="ruut">
    </div>
    <script>
var wtf = renderLogin();
document.getElementById("ruut").appendChild(wtf);
    </script>
  </body>
<html>

All we are doing here is creating a simple html file with a div called 'ruut' and two lines of Javascript. The first will call the 'renderLogin()' function we created in our 'test_render.js' file and assign its output to a variable named 'wtf'. The second simply appends this output to our div named 'ruut' using the standard DOM appendChild() method. 

Finally, in the 'dist' directory will be two files. Open each and copy the contents of them into the html file right after the '<script>' tag (normally something called webpack does this as part of the build process but here we will do it manually). When you are done your html file should now look something like this 

test.html
--------
<html>
  <head>
  </head>
  <body>
    <div id="ruut">
    </div>
    <script>

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

var renderDom = function renderDom(name, props) {
  for (var _len = arguments.length, children = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
    children[_key - 2] = arguments[_key];
  }

  var el = document.createElement(name);
  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = Object.entries(props)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var _ref = _step.value;

      var _ref2 = _slicedToArray(_ref, 2);

      var key = _ref2[0];
      var val = _ref2[1];

      el.setAttribute(key, val);
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  var _iteratorNormalCompletion2 = true;
  var _didIteratorError2 = false;
  var _iteratorError2 = undefined;

  try {
    for (var _iterator2 = children[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
      var child = _step2.value;

      if (typeof child === 'string') {
        el.appendChild(document.createTextNode(child));
      } else {
        el.appendChild(child);
      }
    }
  } catch (err) {
    _didIteratorError2 = true;
    _iteratorError2 = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion2 && _iterator2.return) {
        _iterator2.return();
      }
    } finally {
      if (_didIteratorError2) {
        throw _iteratorError2;
      }
    }
  }

  return el;
};

/* @jsx renderDom */

function renderLogin() {
  return renderDom("section", {id:"secId"}, renderDom("input", { type: "email", value: "" }), renderDom("input", { type: "password", value: "" }), renderDom("button", {id:"butId"}, "Log In"));
}

var wtf = renderLogin();
document.getElementById("ruut").appendChild(wtf);
    </script>
  </body>
<html>


Simply double click this file (after you save it to your desktop) and you will see your transpiled code running in the browser. Specifically you should see two inputs and a button. Babel has transpiled our ES6 input to plain Javascript; ES4 style. 


WHAT WE DID


So first we created a project for npm to build. This project uses Babel to take any files in the 'src' directory and transpile them and put the transpiled output in the 'dist' directory. This transpiling simply converted a JSX template file (which in our case is really just ES6 code) to an ES4 plain vanilla Javascript file. We did this to two files, 'RenderDom.js' and 'test_render.js'.

If you look at our 'test_render.js' file we see it does not contain very much. Specifically it contains 

/* @jsx renderDom */

function renderLogin(){
  return renderDom("section", null,
    renderDom("input", {type:"email", value:""}),
    renderDom("input", {type:"password", value:""}),
    renderDom("button", null, "Log In")
  );
}

The first line is NOT just a comment. It is known as a 'pragma comment' or 'jsx pragma' or 'custom pragma'. I have seen it called all this and more but these are the most common terms. The technical explanation for this line may be found here

https://babeljs.io/docs/en/babel-plugin-transform-react-jsx#custom

Basically, it is telling Babel what function to use to transform (or transpile) your JSX. In our case we are telling it to the use the function 'renderDom()' which we created in our other file (RenderDom.js).

The rest of this file is vanilla Javascript. In our example, we are using a function called 'renderDom()' instead of the standard React function called 'React.createElement()' which is what JSX is typically used for (to create a React application) and so rather than JSX being converted to React in our example, ES6 is being converted to plain vanilla Javascript, version ES4 by Babel

We defined the function 'renderDom()' in our second file called 'RenderDom.js'. Now what is interesting and why I went through all of this exercise was to see what exactly Babel does when it transpiles a file. Looking at the files Babel output in the 'dist' directory which we copied into our html file is interesting. It didn't do much to 'test_render.js' because it was pretty much just standard ES4 Javascript to begin with, but it did do a number on our 'RenderDom.js' file. Specifically this code

let renderDom = (name, props, ...children) => {
  let el = document.createElement(name);
  for (let [key, val] of Object.entries(props)){
    el.setAttribute(key, val);
  }
  for (let child of children){
    if (typeof child === 'string'){
      el.appendChild(document.createTextNode(child));
    } else {
      el.appendChild(child);
    }
  }
  return el;
}

Was converted to this code 

'use strict';

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

var renderDom = function renderDom(name, props) {
  for (var _len = arguments.length, children = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
    children[_key - 2] = arguments[_key];
  }

  var el = document.createElement(name);
  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = Object.entries(props)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var _ref = _step.value;

      var _ref2 = _slicedToArray(_ref, 2);

      var key = _ref2[0];
      var val = _ref2[1];

      el.setAttribute(key, val);
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  var _iteratorNormalCompletion2 = true;
  var _didIteratorError2 = false;
  var _iteratorError2 = undefined;

  try {
    for (var _iterator2 = children[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
      var child = _step2.value;

      if (typeof child === 'string') {
        el.appendChild(document.createTextNode(child));
      } else {
        el.appendChild(child);
      }
    }
  } catch (err) {
    _didIteratorError2 = true;
    _iteratorError2 = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion2 && _iterator2.return) {
        _iterator2.return();
      }
    } finally {
      if (_didIteratorError2) {
        throw _iteratorError2;
      }
    }
  }

  return el;
};

Wow! That's a lot of code. At a minimum, if we are getting paid for lines of code Babel is our friend :-)

In effect this is the difference between ES4 and ES6. ES6 can be written more concisely than ES4 and it also added some exception handling in there for us for free.

Now let's see what happens when we refactor that method ourselves to use ES4 Javascript. You would think Babel would have nothing to do. Here is our new renderDom() method in old school ES4


// Note IE8 needs polyfill for Object.entries and Object.keys

// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Object.keys = (function() {
  'use strict';
  var hasOwnProperty = Object.prototype.hasOwnProperty,
      hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
      dontEnums = [
        'toString',
        'toLocaleString',
        'valueOf',
        'hasOwnProperty',
        'isPrototypeOf',
        'propertyIsEnumerable',
        'constructor'
      ],
      dontEnumsLength = dontEnums.length;

  return function(obj) {
    if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) {
      throw new TypeError('Object.keys called on non-object');
    }

    var result = [], prop, i;

    for (prop in obj) {
      if (hasOwnProperty.call(obj, prop)) {
        result.push(prop);
      }
    }

    if (hasDontEnumBug) {
      for (i = 0; i < dontEnumsLength; i++) {
        if (hasOwnProperty.call(obj, dontEnums[i])) {
          result.push(dontEnums[i]);
        }
      }
    }
    return result;
  };
}());

Object.entries = function( obj ){
  var ownProps = Object.keys( obj ),
      i = ownProps.length,
      resArray = new Array(i); // preallocate the Array
  while (i--)
    resArray[i] = [ownProps[i], obj[ownProps[i]]];
  
  return resArray;
};


function renderDom(name, props, ...children) {
  let el = document.createElement(name);
  for (let [key, val] of Object.entries(props)){
    el.setAttribute(key, val);
  }
  for (let child of children){
    if (typeof child === 'string'){
      el.appendChild(document.createTextNode(child));
    } else {
      el.appendChild(child);
    }
  }
  return el;
}


Well Babel might have nothing to do but we certainly had a lot to do.

Now you might be wondering what happened to our simple renderDom() method. Well first, if we are worried about backward compatibility with IE8 (and isn't everybody), then even ES4 has issues, specifically, IE8 (or older) does not support Object.entries() nor Object.keys(). As a result, we have to create a polyfill for both methods just to allow our renderDom() method to compile. Note that we could have also chose to refactor renderDom() to not use Object.entries() but it would have gotten ugly in a hurry and that's kind of the point. This is exactly what Babel is is good at. Specifically it will handle all of this for us so we can concentrate on writing good clean Javascript without having to worry about ES4 versus ES6 and browser incompatibilities. Babel handles all that for us, and more.

Here is what Babel transpiled our converted renderDom.js to 

'use strict';

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

// IE8 needs polyfill for Object.entries and Object.keys

// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Object.keys = function () {
  'use strict';

  var hasOwnProperty = Object.prototype.hasOwnProperty,
      hasDontEnumBug = !{ toString: null }.propertyIsEnumerable('toString'),
      dontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'],
      dontEnumsLength = dontEnums.length;

  return function (obj) {
    if (typeof obj !== 'function' && ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) !== 'object' || obj === null)) {
      throw new TypeError('Object.keys called on non-object');
    }

    var result = [],
        prop,
        i;

    for (prop in obj) {
      if (hasOwnProperty.call(obj, prop)) {
        result.push(prop);
      }
    }

    if (hasDontEnumBug) {
      for (i = 0; i < dontEnumsLength; i++) {
        if (hasOwnProperty.call(obj, dontEnums[i])) {
          result.push(dontEnums[i]);
        }
      }
    }
    return result;
  };
}();

Object.entries = function (obj) {
  var ownProps = Object.keys(obj),
      i = ownProps.length,
      resArray = new Array(i); // preallocate the Array
  while (i--) {
    resArray[i] = [ownProps[i], obj[ownProps[i]]];
  }return resArray;
};

function renderDom(name, props) {
  var el = document.createElement(name);
  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = Object.entries(props)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var _ref = _step.value;

      var _ref2 = _slicedToArray(_ref, 2);

      var key = _ref2[0];
      var val = _ref2[1];

      el.setAttribute(key, val);
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  for (var _len = arguments.length, children = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
    children[_key - 2] = arguments[_key];
  }

  var _iteratorNormalCompletion2 = true;
  var _didIteratorError2 = false;
  var _iteratorError2 = undefined;

  try {
    for (var _iterator2 = children[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
      var child = _step2.value;

      if (typeof child === 'string') {
        el.appendChild(document.createTextNode(child));
      } else {
        el.appendChild(child);
      }
    }
  } catch (err) {
    _didIteratorError2 = true;
    _iteratorError2 = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion2 && _iterator2.return) {
        _iterator2.return();
      }
    } finally {
      if (_didIteratorError2) {
        throw _iteratorError2;
      }
    }
  }

  return el;
}

That's a lot of code. Looking at the original renderDom.js file is a lot easier on the eyes and probably easier to debug and maintain. It is good, however, to see what exactly Babel does to your code. If you're like me and distrustful of other code wonking your code you can use this approach to actually see how your code was transformed (or transpiled) by Babel. Who knows, maybe it produces a bug under certain circumstances. It wouldn't be the first time a compiler (or in this case transpiler) bit me in the ass. I don't know about you, but at least I'll now be able to sleep better at night.






Tuesday, March 10, 2020

The First Myth Of Management Is That It Exists

My Personal Beliefs on Management


I often like to quote the age-old adage that 'the first myth about management is that it exists'.

Rather I view the role of manager as a facilitator, almost equivalent to an umber grunt. The manager's job is to listen and eradicate blockages with the ultimate goal being to get better utilization out of existing resources. Good managers realize they work for their employees, not the other way around. Micro managing is bad; mentoring is good. Some of my fondest success stories are hiring interns who gradually became full time productive coders who may even out grow the job and leave, but if they want to work with you again, that is the best compliment you can get.

Firing employees is not management. Anybody can do that. Rather converting an unproductive resource to a productive resource is the goal. Obviously part of this requires being able to measure performance but it is deeper than this. Without getting too psychological, programmers are basically artists and they come in all shapes and sizes. Some like to be challenged, some not so much. This is not necessarily a bad thing. Some people love to be given the impossible and get bored at a task they know they can complete in a short period of time while others thrive on being able to quickly complete a task and move on to the next. Some coders produce consistently on a daily basis, others go through down periods where their output is barely discernable but then bam, they go through a period where they produce some fantastic results in a short period of time. A manager's job is to understand the individuals as well as to be able to measure their performance and create a plan of success based on the individual's unique characteristics.

I also believe in positive versus negative reinforcement. Most people respond to accolades and atta'boys better than having their mistakes amplified. Good programmers enjoy the ability to show others how creative and intelligent they are. They like to share their success stories far better than their failures even though we can all learn from our failures. It is more productive to allow them to surface their mistakes and show how they eventually got on the right path rather than to lament the lost time they spent going down the wrong path. Subtle peer pressure is far more effective in motivating coders. I can't think of one time a boss yelled at me and my take away was, boy do I want to work harder for that guy.

While business is not always a democracy I do believe that consensus works better than trying to impose one's will on others. An example of this is the conventions surrounding an organization's code base. The placement of curly braces, the level of indentation, the design patterns used, etc are better to come from group consensus rather than some big dog imposing their will on the team. Understanding that while 'this is how we have always done it' produces consistency, maybe 'this is a better way to do it' is an important part of constant process improvement and constant process improvement should always be a goal since perfection is a myth.

A good manager should always be trying to mentor their co-workers and encourage them to communicate what they like to do and what they don't like to do. In this way, you can avoid giving folks tasks they are not motivated to accomplish. At Amazon I worked with tons of project managers who were Harvard MBAs who considered the work they were doing below their dignity. As a result a lot of these project managers did not do a very good job of managing their project. A healthy engineering organization in my mind (which is actually anti-Amazonian) is not a bunch of PHDs who are gifted geniuses but rather a mix of younger coders who are learning on the job, mid tier guys who just love doing the work, and guys who are already at the top of their game. In this way you have resources who are not always doing something they consider grunt work. One person's grunt work is another person's challenging and fun task. Part of a manager's job is figuring this out.

Finally, on a personal note, I like fungible assets. This allows me to run a Kanban type operation rather than strictly Agile. In Kanban, workers pull the next request from the board and can often select which task they would prefer to do. While this is not always possible it is a goal. To this end I like paired programming where periodically, coders of differing skill sets are paired with the goal being cross training. Maybe a front-end coder and a back-end coder pair up on a task with the goal being they will cross-pollinate. Over time you may end up with two coders who can both do front-end and back-end work which means at some point in the future someone can take a vacation and the organization doesn't come to a screeching halt. Kanban is also designed as a ground up constant process improvement discipline where changes in how things are done are initiated by the actual people who do them rather than some ivory tower type who may or may not get it.

Obviously all this takes time to develop and is based on the concept that an organization is growing and evolving over time. Change can be disruptive in both directions and organizations sometimes just have to get work done quickly in order to meet higher order business objectives. Keeping the lights on should always take priority but it doesn't mean constant process improvement needs to stop. Knowing how to balance these seemingly competing priorities and when to take the time to pay down technical debt as well as when to move on to new technologies is part of what goes into effective management which as my opening quote claims, doesn't exist :-)


Unemployed Again and the Javascript Fat Arrow

As is often the case when I become involuntarily unemployed I find myself with free time on my hands.  I was recently working as contractor for Hilton Hotels indirectly for a recruitment agency known as Apex. What I learned from this experience is you should read the contract. In this case it simply said if I want to quit I must give them a two week notice but if they no longer require my services they can just tell me that day. While they weren't that draconian in this instance (they told me Thursday that the next day Friday would be my last) I still don't view this as an equitable exchange and so in the future I will be sure to amend the contract one way or the other or just not take the job.

But I digress. Having free time on my hands allows me to catch up on the new stuff I am normally missing out on because when I am working full time I very rarely have free time on my hands and that which I do is typically consumed by my wife. For some reason this woman wants to constantly be around me and consume my time with small talk and other trivial stuff so unfortunately when I am working I have little to no time to catch up on what's new and exciting with my favorite tools.

Such is the case with Javascript because even though I have been using Javascript productively since around 1999, it seems I am not aware of the foundational concepts on which it is predicated and the way those concepts have been expanded and used. It is one thing to know a language such that you can produce working code. It is far different to have an academic understanding of the language. I learned this several years ago when I befriended a professor at the local university. He was teaching Python and while I had been using Python every day it was apparent he knew a lot more about Python than I did even though he had never written a line of Python that was used in a production environment.

Anyway, back to the topic at hand, the 'fat arrow'. While some might say the fat arrow is basically syntactic sugar for function declarations this would be doing a great disservice to the fat arrow. In fact it differs from standard Javascript function declarations in a variety of ways.

A) Syntactical Differences
First, the syntactic sugar.
function someFunc() {          // decalre a function with no arguments
const someFunc = () => {       // declare a function with no arguments

function someFunc(props){  // decalre a function with a single argument
const someFunc = (props) => {  // declare a function with a single argument
const someFunc = props => {    // also declare a function with a single argument

// and finally we have this parameter free syntax
const things = [{name:'thing1', price:'10'}, {name:'thing2', price:'20'}];
console.log(things.map(prices => prices.price));
B) Use as a Constructor
Another difference between functions defined using the fat arrow and standard Javascript functions is that functions defined using the fat arrow may not be used as constructors.

C) Use as a Generator
Functions defined using the fat arrow syntax can’t be used as generators. Using the yield keyword in a function defined using the fat arrow will throw an error.


D) Implicit Return Value
When using normal functions there is no implicit return value. You must use the return statement to return a value from a function defined using the standard function syntax. Functions defined using the fat arrow syntax CAN POTENTIALLY have an implicit return value.
const someFunc = () => 'boo'
someFunc()      // returns 'boo'

For an arrow function to have an implicit return an expression is required. But in JavaScript, many language constructs are not expressions but are statements. In fact, for a function defined using the fat arrow if it has a statement in its body it must be defined using curly braces and as soon as you have curly braces surrounding your function body, returns are no longer implicit – for either statements or expressions.

const broken = () => { 'who cares' }
broken()       // returns undefined
const thisWorks = () => { return 'boo who' }
thisWorks()     // returns 'boo who'

Our old pal the ternary operator allows an expression, and as was previously mentioned an expression can be returned.

function ternary() { return true ? 'Yup' : 'Nope' }
ternary()     // returns 'Yup'


E) Return Values
If you want to return objects from an arrow function, you need to wrap them in parentheses.

const details = name => ({ firstName: name }); // will return an object
const details = name => { firstName: name };   // will return undefined

Not so using the funnction syntax to define a function.

function syntax1(){
  let someObj = {first:'Joe', last:'Blow'};
  return(someObj);
}
function syntax2(){
  let someObj = {first:'Joe', last:'Blow'};
  return someObj;
}
console.log(syntax1()); // prints { first: 'Joe', last: 'Blow' }
console.log(syntax2()); // also prints { first: 'Joe', last: 'Blow' }

F) This is Now Lexically Scoped
Finally, the meaning of 'this' is different for a function defined using the function syntax versus a function defined using the fat arrow. Instead of trying to describe what 'lexically scoped' means I'll simply show you an example I saw somewhere which I copied (sorry to the author but I forgot the link and I can't seem to find it again). Without just showing you the code though I'll try to explain briefly using my own experience.

Before the fat arrow, 'this' referred to the thing you were running, so to get the desired behavior in a function that was passed to the timer I would have to use the trick of using a closure to define a variable (some like myself would call this variable 'self' or 'that') and then we would get the desired behavior. Being the chucklehead I am I had no idea Javascript functions had a default function called 'bind()'. While the closure trick still works with normal functions it is no longer necessary if you use the fat arrow to define your function. The following code which you can simply copy and paste into a file on your desktop which you then just double click on to see it in action in your default browser should demonstrate the concept better than a bunch of words.

<html>
  <head>
    <script>
// globally defined this.i
this.i = 100;
var counterA = new CounterA();
var counterB = new CounterB();
var counterC = new CounterC();
var counterD = new CounterD();
// bad example
function CounterA() {
  // CounterA's `this` instance (!! gets ignored here)
  this.i = 0;
  setInterval(function () {
    // `this` refers to global object, not to CounterA's `this`
    // therefore starts counting with 100, not with 0 (local this.i)
    this.i++;
    document.getElementById("counterA").innerHTML = this.i;
  }, 500);
}
// manually binding that = this
function CounterB() {
  this.i = 0;
  var that = this;
  setInterval(function() {
    that.i++;
    document.getElementById("counterB").innerHTML = that.i;
  }, 500);
}
// using .bind(this)
function CounterC() {
  this.i = 0;
  setInterval(function() {
    this.i++;
    document.getElementById("counterC").innerHTML = this.i;
  }.bind(this), 500);
}
// fat arrow function
function CounterD() {
  this.i = 0;
  setInterval(() => {
    this.i++;
    document.getElementById("counterD").innerHTML = this.i;
  }, 500);
}
    </script>
  <body>
    Bad Example. This code is actually broken:<span id="counterA">0</span>
    Using a closure: <span id="counterB">0</span>
    Using 'bind':<span id="counterC">0</span>
    Using the fat arrow: <span id="counterD">0</span>
</html>


So now you know everything I know about the fat arrow.