Book Review:Build your own AngularJS


As part of my continuous learning; I started reading Tero Parviainen‘s ‘Build your own AngularJS‘ about 6 months ago. After 6 months and 127 commits, I am grateful I completed the book.

While I didn’t take notes while reading, some ideas stood out. Thus, this post describes some of the concepts I have picked up from the book.

The Good

1. Get the foundational concepts right

This appears to be a recurring theme as I learn more about software engineering. Just as I discovered while reading the SICP classic, nailing the right abstractions for the building bricks makes software easy to build and extend.

Angular has support for transclusion which allows directives to do whatever they want with some piece of DOM structure. A tricky concept but very powerful since it allows you to clone and manage the scope in transcluded content.

There is also support for element transclusion. Unlike the regular transclude which will include some DOM structure in some new location; element transclusion provides control over the element itself.

So why is this important? Imagine you can add this to some element to only show up under certain conditions? Then you can use element transclusion to ensure that the DOM structure is only created and linked when you need it. Need some DOM content to be repeated times? Just use element transclusion, clone and append it the times. These two examples are over-simplifications of ng-if and ng-repeat respectively.

Such great fundamentals allow engineers to build complex things from simple pieces – the whole is greater than the sum of parts.

2. Test Driven Development (TDD) works great

This was my first project built from the scratch using  TDD and it was a pleasant experience.

The array of about 863 tests helped identify critical regressions very early. It gave me the freedom to rewrite sections whenever I disagreed with the style. And since the tests were always running (and very fast too, thanks Karma!); the feedback was immediate. Broken tests meant my ‘refactoring’ was actually a bug injection. I don’t even want to imagine what would have happened if those tests didn’t exist.

Guided by the book – a testament to Tero’s excellent work and commitment to detail – it was possible to build up the various components independently. The full integration only happened in the last chapter (for me, about 6 months later). And it ran beautifully on the first attempt! Well, all the tests were passing…

3. Easy to configure, easy to extend

This is a big lesson for me and something I’d like to replicate in more of my projects: software should be easy to configure and extend.

The Angular team put a lot of thought into making the framework easy to configure and extend. There are reasonable defaults for people who just want to use it out of the box but as expected, there would be people who want a bit more power and they can get desires met too.

  • The default digest cycle’s repeat count of 10 can be changed
  • The interpolation service allows you to change the expression symbols from their default {{ and }}
  • Interceptors and transform hooks exist in the http module
  • Lots of hooks for directives and components

4. Simplified tooling

I have used grunt and gulp extensively in the past however the book used npm in conjunction with browserify. The delivery pipeline was ultimately simpler and easier to manage.

If tools are complex, then when things go wrong (bound to happen on any reasonably large project), you’d have to spend a lot of time debugging or trying to figure out what went wrong.

And yes, npm is powerful enough.

5. Engineering tricks, styles and a deeper knowledge of Angular

Recursion

The compile file which would allow two functions to pass references to each other – an elegant way to handle state handovers while also allowing for recursive loops.

Functions to the extreme

  1. As reference values: The other insightful trick was using function objects to ensure reference value integrity. Create a function to use as the reference.
  2. As dictionaries: functions are objects after all and while it is unusual to use them as objects, there is nothing saying you can’t.

function a() {};

a.extraInfo = "extra"

Angular

Most of the component hooks will work for directives as well – in reality, components are just a special class of directives. So you can use the $onInit, $onDestroy and so on hooks. And that might even lead to better performance.

Issues

Tero did an awesome job writing the book – it is over a 1000 pages long! He really is a pro and knows Angular deeply; by the way, you should check out his blog for awesome deep dives.

My only issues had to do with issue resolution; there were a few issues with outdated dependencies but nothing too difficult. If he writes an Angular 2 book, I’d like to take a peek too.

Conclusion

I took a peek at the official AngularJS repository and was quite surprised by how familiar the structure was and how it was easy to follow along based on the concepts explained in the book.

I’ll rate the book about 3.9 / 5.0. A good read if you have the time, patience and curiosity to dive deep into the  Angular 1 framework. Alas Angular has moved on to 2 but Angular 1 is still around. Moreover, learning how software is built is a great exercise always.

Maturing as a software engineer


Looking back on my time as a developer, there are a lot of things I would have avoided doing if I had as much knowledge and maturity as I did now.

While I am grateful for the experiences and don’t regret them; I felt it would be a good idea to share these. These might motivate others or at least speed up their careers.

Here goes!

1. Patterns, patterns, patterns

When I take part in code reviews, I tend to look for recurring style patterns. Why? This helps to reduce the cognitive load on readers of the code (after all, code is written to be read).

I am  not advocating for bad software patterns rather having a plethora of ways for doing the same thing in a codebase creates confusion and productivity losses. How do you determine the ‘right’ pattern?

For example in JavaScript, there are several ways for creating an array.


var a = [];

var a = new Array();

var a = new Array(3);

Having a haphazard mixture only takes away brain processing cycles. Rather, have your team decide on a style and stick to it.

By the way, the first style is the ‘expected’ and preferred approach although there might be use cases for the latter two.

Ever wonder why the Google codebase is rated to be easy to work with? Well, think about consistency and established patterns.

2. Break the big picture down and make incremental progress

Building and distributing the smallest software piece you can imagine requires more effort than you would think. It is much more efficient to break down the big picture into small chunks of work that can be completed in an hour or less. Such breakdowns make you more effective and help in understanding progress and forecasting completion times (which is a tricky problem to solve).

I used to break down only the code pieces before (which itself was an improvement over my earlier dive-into-code-and-figure-it-out-as-you-go approach). Nowadays, I try to take some time and reflect on the end product itself: its behaviour, look and feel and how users would interact with it.

For a typical software project, such road maps covers:

  • Testing – unit tests, continuous integration,
  • Documentation – extensibility guides, tooling
  • Implementation
  • Discoverability and Distribution – release targets, getting started articles
  • Maintenance – handling bugs, user feedback etc

Sounds like too much work? Well, just focus on one small bit at a time and keep making progress.

3. Be lazy – start first on tasks with the largest impact/effort ratios

Two things matter: results and impact. There is no point in slaving for 20 hours to choose between blue and light blue if it has no impact on the users. Ditto for spending endless hours ‘arguing’ over what language should be used. Just choose the best usable one and deliver results.

My heuristic for tasks is thus:

  • Does completing the task move me closer towards the big picture?
  • Is this the easiest-to-achieve task with the biggest impact?

If so, I pick up that task and just do it – the goal is to maximize the impact/effort ratio.

Before I’d just stick to a task and spend endless hours on it even if it was something as trivial (and probably low-impact) as beautifying test scaffolding test output and elaborately designing test functions. Now? Common, my time is more valuable than that – I get the test functions right and try to get the coverage I want but won’t spend too much time once that is achieved and is readable for others.

Excessive polishing time can be spent on other more impactful pursuits like having fun with family or delivering high impact features.

4. Technical skills plateau

Sooner or later, you’ll get to the technical plateau. By that time, you’ll have so many successes under your belt and can detect potential pitfalls easily. Then, what next?

There are tons of ways to extend your impact and that is the way people become even better engineers. For example, I doubt if Anders Helsberg is still writing a lot of code, yet his ideas continue to empower and influence millions around the world.

Think about that, how do you scale your influence and make it possible to touch the lives of thousands of people? Are there engineering problems crippling your organization? Process pitfalls to improve with huge impact? Education ramp ups? There are always challenges to solve and problems to fix.

5. Choose career investments carefully

How would you set up an investment portfolio? Would you just go about investing in everything? Nope, you would evaluate the risks and benefits, consult experts and then invest in a select few areas while ignoring other areas.

You could spread out your risk by investing in a wide area but doing this excessively dilutes your returns. Conversely, investing in only company could be very risky too. Thus, it’s generally advised to spread  out your investment portfolio

Careers are investment portfolios. A typical career spans a long period ( upwards of 30 to 40 years) and shares some similarities with investments:

  • technologies, frameworks etc -> investment options
  • time -> funds

Just as you wouldn’t jump on every new fund, why would you do the same with your career? There is no harm in taking measured risks in careers but you should be strategic and know what your end goal is.

Every now and then a new framework pops up in the news. Before, I’d hop on the bandwagon and try figure it out. Nowadays? Well, if it really piques my interest, then I might spend some time learning about its core design principles and problem-solving approach.

If it neither solves any of my problems nor brings anything new to the table, then no thank you; I’d rather continue nurturing my current investment portfolio and hedging my bets.

Think about your bets and stick to them.

Conclusion

I am still learning and pray I continue. One thing that has struck me as being really critical is the will to try. We don’t know if something would work out or not however we can always try and then learn from the outcome (success or failure).

Don’t give up – continue learning and growing.

Defining JavaScript Functions


There are many ways to create functions in JavaScript; some styles are quite popular e.g. the function declaration and function expression while others are not.

//function samples
function declaration () {};
var funcExpression = function () {};
var namedFuncExpression = function named() {};
var fnConstructor = new Function ();

All approaches create a Function object however there are a couple of differences under the hood. Lets take a peek…

1. Function Declaration

The function declaration pattern is one of the most common patterns.


function fn () {
    //function body
}

Once a function is defined using the declaration format; it can be used anywhere in the enclosing scope even before the function body. Confusing? It’s all about hoisting.

2. Function Expressions

Functions are first class objects in JavaScript, thus it is possible to have expressions that evaluate to function values; such expressions are appropriately termed function expressions.

Creating a function expression is easy: just declare a function where the parser expects an expression and it automatically becomes a function expression. This includes assignments to variables and/or object properties, placing functions between parentheses (the grouping operator can only contain expressions),or after a unary operator (e.g. !, +, – etc).

//anonymous function expressions
var fnExpr = function () {};

(function fnExpr2() {} );

!function fnExpr3() {}

Function expressions can be named or anonymous; named function expressions (NFE) expose a function name that is available inside the function body but not outside it. See the snippet below:

var namedFuncExpression = function named() {
    return named.name;
};

named();
//ReferenceError, named is not defined

namedFuncExpression();
//returns "named"

NFEs help to make debugging nicer (we all know how frustrating it is to keep seeing ‘anonymous’ functions in the debugger). It might also come in handy when you need to retrieve a function name by calling toString() or make recursive functions (although the variable name will also serve the same purpose).

Function expressions are essential to achieve functional programming concepts like currying and partial application in JavaScript.

3. Function Constructor

The last way is to use the function constructor, this constructs a function object and returns it.

There are a few things to note while using this approach: created functions can only access variables in the global scope or in their own scope and it is no possible to create closures. Moreover, the use of the function constructor is slower since the function body has to be parsed every time it is called. And there are potential risks from malicious agents.

var add = new Function('a','b', 'return a + b');

add(1,2);
//3

var glbFoo = "global";
function scope() {
  var scpFoo = "scoped";,
   scop=Function('console.log(typeof scpFoo)'),
   glob=Function('console.log(typeof glbFoo)');

   scop();
   glob();
}

scope();
//logs undefined
//logs string

The parameters to the function are passed in first and then the function body (as a string) is passed in as the last parameter and viola! the function object is returned. The new keyword is optional; it still works without the new.

4. Function expression vs Function declaration

Function declarations and their bodies get hoisted to the top of the scope (no matter where they appear – top, bottom or middle) and are thus available through the scope. However for function expressions, the variable declaration is hoisted while the assignment to the function body only happens at runtime. See the example below:

declared();
//logs declared
function declared () {
    console.log('declared');
}

expressed();
//logs TypeError: undefined is not a function

var expressed = function () {
    console.log('expressed ');
}
expressed();
//logs expressed

5. Spot the difference? Identifying function expressions and declarations in code

Differentiating between function expressions and declarations can be tricky. According to the ECMAscript specification, function declarations must have an identifier. If functions without identifiers are unequivocally function expressions, how do we distinguish between a function declaration and a named function expression?

Function declarations are only allowed as sourceElements of scripts or functions. They cannot appear in nested blocks because blocks are  only allowed to contain statements and not sourceElements. Expressions on the other hand are expressions… 🙂

//source element examples
var a = 0;
function b () {};
if (false) {
    //nested, not source element
    var c = 0;
    function d () {};
}

//function declaration
function foo() {
    //another declaration
    function bar() {};

    if(true) {
        //function expression because
        //it is not a source element
        function baz() {};
    }

    //function expression
    //expressions expected after unary operator
    !function bng () {};
};

6. Finally…

Still reading? Here are some more examples of queer ways to create functions. Don’t do this at home/work/live/staging/etc.

var f = function (str) {
    alert(str);
};
eval('f("eval")');
//alerts eval

setTimeout('f("timeout")',1000);
//alerts timeout after a sec
};

Remember, don’t do this on live servers…

Did you enjoy this post? Here are a couple more interesting posts:

1. The JavaScript Function
2. Three Important JavaScript Concepts
3. A peek into JavaScript’s Array.prototype.map and jQuery.map

Update

Brilliant explanation of the difference between function and Function by Peter van der Zee:

“The `Function` is a global object and a function value, which generates a new function when called. You create new local variables named `Function` but not with `function` “

Three Important JavaScript Concepts


Statements and Expressions

The MDN documentation defines JavaScript expressions as any valid unit of code that resolves to a value.

a = 1;
3 + 4;

The first expression has value 1 which is then assigned to variable a while the second has value 7 which is not assigned to anything.

Since expressions evaluate to values (numbers, strings, functions etc), they can be substituted anywhere these values are expected. Programmers just have to ensure expressions resolve to expected values because of JavaScript’s weak typing.

Consider the following simple statement:

var x = "statement";

This is a statement and not an expression. Statements do something while expressions evaluate to values.

Dr. Axel has an excellent post which differentiates both: “you can use expressions where statements are expected (these are called expression statements) however you cannot use a statement where an expression (i.e. something that evaluates to a value) is expected”.

To simplify; you cannot use the statement above as a condition for an if branch (which expects an expression or value).

Variable Scope

Scope determines the lifetime of variables and where they can be used. Most programming languages have block scope, i.e. variables only exist within enclosing blocks (usually delimited by braces). However, JavaScript has other ideas… Check the code snippet below.

function JSBlockScope() {
    var noBlockScope = "BlockScope";
    if(true) {
        var noBlockScope = "FuncScope";
    }
    console.log(noBlockScope);
};

JSBlockScope();
//logs FuncScope

The output is “FuncScope”! Surprised? Block scope implies that declarations inside blocks do not overwrite external variables. JavaScript has function scope and consequently noBlockScope gets overwritten to ‘FuncScope’.

Function scope also means that variables declared inside functions are only available inside those functions, once the function exits, the variables are inaccessible anymore (well, unless you use closures…).

function scopeCheck() {
    var functionScope = "inside Func";
    console.log(functionScope);
};

scopeCheck();
//logs inside Func

console.log(functionScope);
//ReferenceError: functionScope is
// not defined

The functionScope variable defined inside the scopeCheck function only exists inside the body of the function.

Variables are first looked up in the current scope (i.e. the enclosing function), if not found, then the interpreter continues walking up enclosing scopes until it gets to the global scope. If the variable is not defined still; then the well-known “ReferenceError: variable is not defined” error occurs.

Hoisting

JavaScript has this weird but fascinating concept called hoisting. All variable declarations are hoisted – every variable gets declared immediately even though their values might not be set immediately.

function hoisting() {
    console.log(hoistedVar);
    var hoistedVar = "hoisted!";
    console.log(hoistedVar);
}

hoisting();
//logs undefined
//hoisted!

Explanation

Confused? Well what happens is that all declarations are hoisted to the top before any code execution begins. The above code is totally similar to the one below:

function hoisting() {
    var hoistedVar; //undefined
    console.log(hoistedVar);
    hoistedVar = "hoisted!";
    console.log(hoistedVar);
}

hoisting();
//logs undefined
//logs hoisted!

The log statements show ‘undefined’ since this is the default value for uninitialized JavaScript variables. If they weren’t hoisted, the interpreter would have thrown a ReferenceError. 

Hoisting also applies to functions (JavaScript functions are values afterall…) however there is a subtle difference between function declarations and expressions. Function declarations get hoisted to the top and are immediately available within the scope while function expressions are only declared and not hoisted (much like the same case for variables above). 

function isFunc(fn) {
    var isFn = (typeof fn === 'function');
    console.log(isFn);
}

function isUndef(fn) {
    var ntDef = (typeof fn === 'undefined');
    console.log(ntDef);
}

function funcHoisting() {
    isUndef(declaredFn); //false
    isUndef(hoistedFn);  //true

    function declaredFn () {};
    var hoistedFn = function () {};

    isFunc(declaredFn); //true
    isFunc(hoistedFn);  //true
}

funcHoisting();

Declaring variables at the top of functions helps to avoid hoisting surprises.

Conclusion

I was going to write about function expressions vs declarations, however I believe these three JavaScript concepts would significantly make it easier to understand that topic. Insha Allaah I’ll publish the function expression vs declaration post next.

Meanwhile, here are some other posts you might like:

1. The JavaScript Function
2. A peek into JavaScript’s Array.prototype.map and jQuery.map
3. Programming Language Type Systems I

Becoming a Professional Programmer


1. Deliver when you commit

It is extremely bad for your reputation to fail to meet up to your words; if you can’t deliver, please say no or find an alternative way out. How would you feel if an artisan disappoints you for no good reason? I bet you’ll probably never do business with them again.

So before you commit to anything (boring bug fixing, dreary testing or documentation), please make sure you’ll deliver or else do not commit.

2. Stay up to date

Do you know design patterns? Development methodologies? The latest fad in software development? Don’t neglect learning else you’ll wake up one day and realize that you are writing COBOL (OK, this is an exaggeration but you sure do get the hint). Staying up to date is your responsibility and no one else’s.

Dedicate time to make sure you know your field very well, ideally it should be time off work and gains should be measurable. While you are at it, please remember not to burn out, create time for fun things too.

Some employers actually make this easy by training employees or providing libraries – if you are lucky enough to have this, please take full advantage of this :); otherwise, there are tons of free stuff on the Internet that you can leverage – blogs, newsletters etc.

3. Be responsible

You must unconditionally know HOW and WHY your code works; and when testers find a bug, accept it as your doing graciouslyThis also applies to inherited code – no one wants to know if the code is spaghetti (with some onions and meat included) or written in Japanese. Once you inherit the code, it automatically becomes your code and it’s up to you to know how it works, what it does and how to fix/extend it.

If you are stuck with such bad code, why not try cleaning it up slowly? Every time you open the file, just make a tiny improvement (please no new bugs).

4. Know the domain

Most developers feel that users are not ‘smart’ enough to understand the intricacies of software development. Software development is complex but so are financial accounting, quantum physics , economics and a whole slew of other fields.

Imagine two developers working on a financial accounting product, the first writes software based on the requirements alone while the second makes a conscious effort to learn more about financial accounting. Who do you think will write better software and communicate more lucidly? Who will understand the problems, issues and challenges better?

Admittedly, it is more work trying to understand accounting (or any other field) but in the long run, it’ll pay off because you’ll write code in the problem domain. This also gives you the chance to contribute meaningfully to the project, proffer advice and analyze the competition. Who knows, it could open the door to new opportunities.

5. Work consciously

Most times we do things because we are accustomed to having things work that way – in coding, code design or requirements gathering. Ideally, we should always be thinking of our work – it should not just be the same ol’ thing all the time.

There are things to try, new (and probably better/more efficient) ways to write code and arcane language features to explore. Always keep asking these questions – why am I doing this? What am I doing now? Is there a better way to do this? It applies to everything – coding, design, maintenance and even meetings! Yes, meetings! 🙂

Did you enjoy this piece? Maybe you’ll also like becoming a better programmer and 5 things I learnt from Code Complete 2.

 

Taking the PAIN out of coding


Over the years, I have learnt some tricks and picked up some lessons while writing code. Most were learnt the hard way, so I decided to share a couple of tips on how to avoid development pitfalls.

Meticulous Planning and Design

One of the most difficult lessons I learnt in software development was not to rush into code; I used to jump impulsively into software projects and start hacking away at code without planning fully. And as you can bet, the thrill of coding soon evaporated when I got bogged down by messy code. Sadly, many projects of mine met their nemesis this way.

Now, I am just too lazy or maybe too battle-scared to do that; I mostly write out a high level system design document (usually a single page or two) describing all the major features. Next, I run through everything to know that the various components and interfaces are logically valid and try the edge cases. Only when I am satisfied with this do I start writing code.

Alhamdulilah, I think I write cleaner, more modular and better designed code this way. For example, I recently had to extend an experimental framework I wrote a couple of months back; surprisingly I was able to make all major changes in less than two hours. Better still, nothing broke when I ran the framework again!

A dev lead once told me coding is the easiest part of software development… I think I agree with him…

Do it fast and dirty, then clean up

I started using EmberJS last year for a web project. EmberJS is a really cool framework and reduces the amount of boilerplate code you have to write: it’s so powerful that some things seem magical. However, EmberJS has a really steep learning curve.

As usual, I was trying to write perfect code at my first attempt, did I succeed? Your guess is as good as mine. I got so frustrated that I started hating EmberJS, the project and everything remotely related to the project. 🙂

Before giving up, I decided to have one more go at it; my new approach involved ignoring all standards and good practices until I got something to work. And that was it, I soon got ‘something’ that looked like a working web application running. One day, while working on the ‘bad’ code, I had an epiphany. In a flash, I suddenly knew what I was doing wrong. Following standards and practices was relatively easy afterwards.

Looking back, I realize that if I was bent on doing it perfectly at the first go I most probably wouldn’t have gotten to this point. Oh by the way, EmberJS got a new release so my code is obsolete again. 😛

Clean up the code from step 2 above X more times

This is a part of development I don’t think I really like but it is essential for maintenance. You have to go back through the code (yes, your code; you ain’t gonna make life miserable for the developer inheriting your codebase). Refactor all duplicated, extraneous and obscure pieces of code ruthlessly. Most importantly, improve the readability of the code (yes, readability is REALLY important – make it read like a good novel if possible à la Shakespeare or Dickens).

I also keep a running list of all the hacks I make as I go about writing code in step 2; this list comes in handy at this stage and enables me to go straight to the substandard code pieces and fix them up.

Use a consistent coding style

I recently noticed that my coding style was inconsistent across my projects: variables names were either under_score or camelCase while method declarations used brace-on-new-line and brace-on-same-line approaches.

The problem with this approach is that it breaks up my flow of thought and makes speed-reading code difficult. Now, I choose a single style and stick to it throughout a project – any style is fine provided I use it consistently.

Scientific Debugging

I came across the term ‘scientific debugging’ while blog-hopping and it has stuck in my subconsciousness ever since. Identifying bugs can be a challenge: for small projects, I just try to figure out where the bug might be and then check for this. However, this approach does not scale, I wouldn’t randomly guess on a 5000 line project.

Scientific debugging is a systematic process: you make hypotheses about the likely causes of the bug, make a list of places to check and then go through this systematically while eliminating entries. You’ll most probably find the bug with less effort and without running through the entire list.

Project Management

I rarely used to track how much time and effort I put into my projects; I would just code and code and code. Now I know better, I estimate how many hours I can put in before, during and after each project. I try to use Agile (although, I use a simple list + pomodoro too) for project planning, task management and effort estimation. It is now trivial looking up my project status: implemented features, issues list and proposed features.

Testing

I tried my hands at TDD last year and I felt it was just a way of doing too much work for coding. While I might be wrong about TDD, I think it’s essential to have a solid testing process in whatever project you’re doing.

Test, test and test: run the gamut (if possible): unit, integration, functional, stress, regression etc.

Enough said… I have dirty code to polish. If you did find some of the points useful, please share your thoughts and ideas.

Related Posts

  1. Symptoms of Software Rot
  2. So you want to become a better Programmer
  3. Clean code, Dirty code

Book Review: Coders At Work: Reflections on the Craft of Programming


I recently completed reading Coders at work (well, I must have spent approximately 8 weeks trying to complete it; not a record I am proud of but still it’s better than nothing!)

I think the book is a good read even though some of the interviews dragged on for too long. Peter Siebel, the author, does a good job of posing broadly similar questions to all the coders he interviewed. He nearly always asked each and every one of them about their coding techniques, most difficult bugs encountered, tools and debugging techniques, how to become a better programmer and how they learnt to program.

He interviewed 15 different programmers ranging from language designers and creators ( Brendan EichJavaScript, Joe Armstrong – Erlang, Joshua BlochJava platform features) to memcached creator (Brad Fitzpatrick, by the way, he wrote memcached at 23 :P). There are also a couple of computer scientists ( Donald Knuth and Peter Norvig) and others too.

Overall; I think the book is a good book and it enables you to see what coding was like back in the days before TDD, Agile, Kanban etc. I found some of the remarks delightfully hilarious and sincere. Most of these folks (including a single woman) were writing code on archaic (well; I bet they didn’t look archaic then) systems.

One unifying theme with all the coders is their love of simplicity and passion for programming. They’ve all spent lots of hours honing and improving their skills; some even know what the error codes of a language signify! Software development has changed a lot since then however the underlying concepts remain the same.

Here are a couple of quotes from the book:

Simple ain’t easy.  Joshua Bloch

A program is a black box. It has inputs and it has outputs. And there is a functional relationship between the inputs and the outputs.    Joe Armstrong

There is a Dijkstra quote about how you can’t prove by testing that a program is bug-free, you can only prove that you failed to find any bugs with your tests. Peter Siebel

Requirements always change… L Peter Deutsch

Programs are meant to be read… Code it as lucidly, as easy to read, as crystal-clear as you can. Do it the simple way.   Bernie Cosell

That’s about it; now go grab a copy if you’re interested.

Clean Code, Dirty Code


Phew! It feels like forever since I wrote a blog post; I have been extremely busy – finished an internship and had to travel back to school. Well, I actually have a couple of drafts but didn’t get to publishing them. Am I too lazy? Na you sabi… :).

I don’t know why I seem to keep talking about code and JavaScript nowadays, I just can’t seem to stop; probably because I think JavaScript is the next BIG thing; what other language is currently experiencing rapid widespread adoption on all major platforms? Read this  and this if you want to know more.

Back to clean code; clean code is what we developers should aspire to write, it is clean, minimal, simple, easy to understand, free of extraneous details, it is simply BEAUTIFUL (there I go again… drooling about software right?). Ideally you shouldn’t be able to remove pieces of it without breaking the system. Less code is always better, the less code you have to write; the better your system. Jeff Atwood actually says the best solution is no code at all.

So what makes code dirty? Anything that makes it a pain to modify, work with or extend. Abstruse code, duplicated logic, global state and variables, tightly-coupled dependencies, contorted flow (I mean those convoluted loops and if constructs), wrongly-exposed variables (it-shouldn’t-be-there-but-I-can’t-help-it-syndrome) etc. In fact, if your codebase doesn’t read easily then you should get into it and clean it up. It’ll go a long long way in saving you painful work in the future. I have worked on a multi-thousand line codebase (> 25k lines and written by lots of people) and found it easy to handle and understand; in contrast I also inherited some smaller codebase (< 4k lines and written by a single person) and it was a pain to extend.

How to get there? Do Code reviews, relentlessly refactor and make sure you don’t leave anything to chance; you have to be professional about your job and code.

Here is an example in pseudocode:

function showMessage(message){
{
    if(message != null){
        show(message);
    }
    else{
        show(defaultMessage); //This is the default action to do
    }
}

Alright; lets clean this up

function showMessage(message){
{
    if(message == null){
        message = defaultMessage;
    }
    show(message);
}

Isn’t the second version just cleaner and easier to use? Here is another example:

    if(condition)
    {
        //do Something
        alertUser();     
    }
    else{
        //do Some other thing
        alertUser();
    }

The alertUser() function is getting called in both conditional branches so it can be moved out. Less code, simpler code, easier to read. Here is the cleaner version:

    if(condition)
    {
        //do Something
    }
    else{
        //do Some other thing
    }
    alertUser();

I feel that writing clean code is even more important than solving the problem you set out to solve. Most of our time is spent extending code, writing fixes and maintaining existing code. Keeping it simple and nice at the start will go a long way in making your job and mine easier.

Levels of Developer Expertise


This is a light-hearted attempt to classify developers. Enjoy…

 1. Newbie

  • Knows the syntax of one language and thinks he’s a master.
  • He might also think the language is the best one in the whole wide world.
  • Full of passion and excitement about programming.
  • Writes code that ‘seems’ to work – it compiles after all – doesn’t necessarily know why it works though.
  • Uses bad variable names.
  • Programs are likely to be be a single file.
  • Doesn’t know anything about testing.
  • Likely languages: PHP or Java.
  • Likely Reads: Learn Java in 21 days or something similar.

 2. Amateur

  • Learns another programming paradigm/language.
  • Uses better variable names – must have been hurt by evil names.
  • Has developed one or two relatively decent working systems.
  • Writes spaghetti code.
  • Re-invents the wheel.
  • Probably has a huge ego.
  • Only knows how to use IDEs.
  • Tests? They are just a waste of time and delay the release of his ‘one-of-a-kind’ software.
  • Still dives into code without proper planning.
  • Likely Reads: Advanced Java.

 3. Intermediate

  • Becomes language agnostic.
  • Knows multiple languages, tools and paradigms – their strengths, flaws and best uses.
  • Has worked on bigger projects – understands the importance of design and flexible code.
  • A bit of spaghetti code here and there but he tries to avoid this.
  • Understands algorithms and data structures.
  • Can use text editors.
  • Uses version control.
  • Designs code before starting and tries to avoid code duplication.
  • Probably has his own blog or contributes to open source projects.
  • Likely Reads: Pragmatic Programmer.

 4. Advanced Intermediate

  • Codes defensively – using asserts, unit tests and checks.
  • Really cares about his code; refactors aggressively until it is clean.
  • Toying with building his own language or at least understands how languages work.
  • Can ‘smell’ bad code.
  • Interested in reuse and sees patterns in software engineering.
  • Understands design patterns.
  • Knows about methodologies like Agile, Scrum, Kanban.
  • Likely Reads : The Mythical man-month, Clean Code, Code Complete, the Java language specifications.

I don’t know much about master programmers – am not one yet though I pray I do get there.

I am curious about what you think, let me know in the comments.

Book Review: JavaScript, The Good Parts


All languages have good and bad parts; to be a master developer in any language, you need to know and avoid the bad parts. Douglas Crockford goes through JavaScript, showing how to write beautiful code in this much-maligned language in an easy-to-follow and understand manner. Brendan Eich developed the language in a rush (I think in about 10 days) and did not have enough time to refine or polish it; so it has more than its share of bad parts. However he got some things right and these actually make JavaScript impressive.

The book is brief and dense but adequately covers how JavaScript should be used. Thanks be to God, I already had some JavaScript experience so it was not too difficult to read along but I still found some concepts confusing (especially regular expressions). Yes, don’t make this book your first JavaScript read, try jqfundamentals(jquery) and/or EloquentJavaScript. I hear David Flanagan’s book is also good.

I absolutely loved his explanation of the four patterns of function invocation. I finally understood what the this  object referred to in the different modes of invocation and also learnt about the that = this;  pattern. I liked his discussion of closures too although I found Nathans‘ explanation to be better.

There is a chapter that describes the api and how to implement some of the functions present in JavaScript; lots of good code. The appendices also describe the bad and awful parts of JavaScript; for example, calling the typeof operator on NaN returns a number which is surprising; the ‘falsy’ attributes (e.g. false, [], ”) have some really intriguing transitive comparisons too.

Overall, I enjoyed reading the book and learnt a lot however I won’t recommend it to beginners. For serious web developers, it is a must-read. (well, to me :)) and I think I’ll have to reread it a couple of times to really understand it well enough.

Lastly, I think JSLint is awesome but a pain to use. What do you think?