Programming Paradigms: An Introduction


A programming paradigm is a way of programming, a style of solving problems and thinking about the domain. Languages directly or indirectly influence programming style; for example, Haskell is purely functional while Python allows a blend of OOP, functional and imperative programming.

Even though most new languages are multi-paradigm, they usually make it easiest to program in a single paradigm; C programs can be written in a functional programming style (instead of the orthodox procedural fashion) –  it is just extremely difficult. Ever wondered why classes are needed to add two numbers in OOP Java?

Paradigms can be viewed as abstractions and metaphors for modelling problems – logic programs can be viewed as theorem solvers; functional programs rely on mathematical models while OOP models real-life objects and their interactions.

Nearly every standard problem can be solved using any of the programming paradigms however some problems are best solved using some paradigms (e.g. recursion vs loops). Thus knowing many paradigms helps programmers in producing very neat and elegant solutions; since they know different ways of solving problems and modelling domains.

Let’s take a shallow dive into some of the popular paradigms.

1. Imperative Programming

imperate: Done by express direction, not involuntary; commanded

In the imperative paradigm, programs are written as a series of instructions that affect global state. It is conceptually similar to cooking recipes which strictly list the steps in preparing a dish.

The imperative paradigm was quite popular until Dijkstra published his famous ‘GOTO considered harmful‘ letter. This fueled the adoption of the structured programming paradigm (albeit at the detriment of imperative programming).

2. Structured Programming

Structured programming is somewhat similar to imperative programming however control flow is defined in terms of loops, subroutines and conditionals; this distinguishes it from the imperative model of jumping around at the heck and bequest of every GOTO call.

The introduction of lexical scoping also helps to prevent the inadvertent overwriting of variables in the global scope.

3. Declarative Programming

Declarative programs have implicit execution: programs say what they want but not how the results should be gotten. SQL is a popular example, have you ever wondered how the SQL engine is able to calculate sums, averages, max etc.

A conceptual example is that of a manager declaring sales targets for his marketing team: the team is smart enough to figure out heuristics and also to go do it on their own (hopefully within ethical and legal limits).

4. Functional Programming (FP)

The functional programming paradigm is a subset of the declarative paradigm. All computation is done using functions – it attempts to do away with the use of variables and value assignments.

Pure functional programs are written as a combination of function calls which have no side effects and return the same result every time they are called with the same input no matter the environment. The elegance of FP comes from the use of higher-order functions (functions which can accept/return other functions e.g. differentiation/integration in the maths domain), referential transparency and high levels of abstraction.

On the other hand, some concepts might be inefficient (e.g. Y combinator) or ugly.

5. Object Oriented Programming (OOP)

This is probably the most popular and probably most widely-used of all programming paradigms. Object oriented programming is built on four major principles – encapsulation, polymorphism, inheritance and data abstraction.

OOP allows the creation of abstract models that mirror real-life objects’ interactions and behaviour. This enables the creation of huge complex software systems having intricate interactions such as state preservation, communication exchanges and behaviour handling.

There are two flavours: classical (where objects are defined and share their characteristics and behaviour based on a class’ blueprint) and prototypical (objects get their behaviour and characteristics from an original prototype object).

Conclusion

Some other paradigms include the event-driven where program respond to events (think web apps) while the logical programming paradigm tries to infer the solution when it is given a set of constraints and or conditions.

Upcoming posts would insha Allaah take a more thorough look at some of the popular paradigms.

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.

 

5 things I learnt from Code Complete 2


My yearning to read Code Complete started early in 2012 – I came across the book in the MASDAR library. Most of it didn’t make sense to me then but I made a mental note to return to it. Alhamdulilah I eventually got a copy of the book around August 2012 but I couldn’t bring myself to read it because of the many pages. Instead I read a couple of smaller books.  I finally stumbled upon goodreads this year and it helped to revive my long-lost book-reading habits.

I made a simple rule – I would make sure I read for about 30 mins everyday: no more no less; I wasn’t bothered about how long it would take or my reading speed, all I cared about was my consistency and understanding of the concepts. I finally finished the book about five months later (sounds like eternity huh?). The book is a little on the verbose side however I learnt a lot – I mean a REAL LOT – and here are my top five lessons from it.

1. Comments might actually imply bad code

It was surprising for me to learn that code with LOTS of comments might actually be bad code, strange huh? Yeah you’re right! Heavily commented code actually implies that the underlying codebase is abstruse and not self-documenting. Ideally code should be simple, straightforward and not need heavily commented

Moreover if comments are not updated when the original code changes, then they’ll become misleading which is even worse than having no comments at all. If you have excessive comments; maybe you should do a review and rework your code. Trust me, most times you’ll end up with cleaner code… OK,  well hopefully :).

Oh, and for those times you write ‘rocket science’ code (aka impossible to simplify), please save future maintainers the stress and do add comments.

2. Project Management

I think one of the most difficult aspects of the software development profession is getting requirements right. Customer perceptions always change and most times people do not even know WHAT they WANT and when they finally do, they want it delivered last week :).

I picked up a couple of ways on how to make this a pleasurable acceptable experience for everyone involved – from developers to project managers to clients. Learn how to say no, estimate project times and methodologies.

3. Leveling up as a programmer

I especially love the ‘Program into your language, Not in it’ quote. Programmers should NOT be limited by the languages or tools they use. If a language does not have a highly desired feature (e.g. asserts, exceptions etc), there is nothing stopping you from implementing your own such features.

Another important point I picked up was the continuous need to consciously improve the quality of my development process. I always get the urge to write quick dirty fixes to problems and the instant gratification of ‘working’ code fuels this bad habit. No, don’t give in! Resist the urge, fight it and crush it! Try to go the extra mile every time you code, that’s the way to grow.

I admit that writing ‘beautiful code’ takes more time and effort however the future savings far outweigh the immediate gains of bad fixes. What is the use of writing quick code in 2 hours and then spending 12 hours to maintain it? It would have been better to spend 6 hours to get it all right.

I once spent about two days trying to get a really critical function to work, I could have written it very quickly (< 2 hours) in sub-optimal ways however it would not have been reusable or flexible or neat.

4. Code is written to be maintained!

I have known for some time that duplicated code is bad and I finally got to really understand why; the issue is with maintenance. Assuming there are three replicated instances of the same code block; if a new programmer updates only one and forgets to update the others, then ‘miracles’ will happen during execution and it is going to be extremely difficult to find the issue.

It is also good to create config files that allow you to make platform-wide changes easily ( I use this a lot now); it makes code much more flexible and you do not really need to dive into some ‘evil’ forest to make changes.

Finally deleting code is a good idea – strange? The smaller the codebase, the fewer the chances of mistakes happening and the smaller the number of things you have to worry about. 🙂

5.  The importance of planning and design

Do not just rush into code, think carefully about the design, how to create re-usable components, how to properly name variables and ensure that code is clean and can be easily extended in the future.

I also adopted the Pseudocode Programming Process (PPP) which has saved me a lot of trouble with coding and design; this is how it works: you write pseudocode of what you want to do and how you are going to go about it – I normally just create a list of numbered steps – then you think through your plan and validate all assumptions.

Afterwards coding should be a breeze and even better, the pseudocode (assuming you leave it in the code) can be converted into cool comments. This approach also helps you to prevent second guessing when you get to tricky situations because you already went through the scenario in the past and wrote it out.

I noticed remarkable changes when I stopped diving into code without thinking. For example, I was able to re-use some  of my existing code to create an admin dashboard in just about 120 minutes; I bet I would have had to start from the scratch otherwise.

Final Thoughts

The size of the book and its verbosity still, Code Complete 2 is a great book and all programmers should read it – you will learn a lot and know what habits to drop.

If you also find it too difficult to understand, put it away for some time and make sure you return to it in about six months. The following quote explains this best:

If you’re a beginning programmer you won’t understand a lot of the material, and if you are experienced, the book will only confirm what you already know. Robert Harvey

The Art of Debugging


I recently wasted a lot of time while attempting to use the amazing Dropzonejs image uploader. I left out a function call in an overloaded function and this broke every subsequent call. More annoyingly, I could not pinpoint the cause of the error as Dropzone was failing silently.

Close to giving up, I decided to give it one more attempt and went to my sandbox – I create a safe area in all my projects for doing ‘risky’ stuff. Starting afresh there, I was amazed to see that everything worked fine. A close comparison of the code samples revealed the bug’s origin – the left out function call. I double-checked to confirm this and that was all about it. Sadly, the documentation does not mention that a failure to call done() in the accept function will break the code silently.

Programmers usually spend a lot of time debugging and it can be a painful experience;  some feel like tearing out their hair in exasperation, smashing their poor computers or even believing that their computers really ‘hate’ them! 🙂

Actually computers do not hate people and the operating system is not conjuring bugs – the most likely reason is buggy code. Here are a couple of tips on debugging; hopefully these will help to reduce time spent, frustration and annoyance levels.

The Inefficient Way of Debugging: Trial-by-Error

Random guesses? Print statements littered around? Fast fixes that ‘appear’ to work? Do these ring a bell? Welcome to the bad bad way of debugging.

This approach is fraught with a gazillion issues. The worst being the potential introduction of new bugs into the codebase. Lucky bug discoveries offer little learning opportunities and it might be difficult to reuse knowledge gained from such fixes in the future.  Also, such run-of-the-mill fixes tend to be inelegant and stand out like a sore thumb when compared to earlier designs and architecture.

The Efficient Ways of Debugging

1. The very first thing is to create a list of the likely causes of the bug; this usually involves thinking deeply about loopholes and design flaws. Studying program error dumps and buggy behaviour might also help.

2. Go through the list while eliminating disproved hypotheses. Once a likely cause is found, a verification needs to be carried out; this can be as simple as proving that the bug appears only when that cause is activated.

3. Don’t just rush to write a fix – I bet you would not want your ‘super-fix’ to mutate into a monster ‘bug’. Think deeply about the bug and what potential ripple effects a fix could have. Also think about how the proposed fix would work, how it blends into the system’s architecture and possible design impacts.

4. Yes, you got it!! Go ahead and squash that bug! Yuck – I dislike bugs.

5. Not finished yet, you need to go through your code armed with your newly acquired bug-terminating powers. Find and ruthlessly sanitize code likely to suffer from such bugs. Rinse and repeat – always leave code in a cleaner state than before.

Extreme Approaches: When the Efficient Ways Fail

You might apply all the above and still be stuck in a rut; this might occur if you have extra-terrestrial bugs (quite popular in multi-threaded environments).

6. Total examination

The brute force approach is bound to work insha Allaah although it involves painstaking work. You go through the code thoroughly (a debugger should come in handy); this might involve examining all execution paths if possible and trying to pinpoint the issue. Hard work…

7. Start afresh

When everything fails, why not throw out the old code and write it again?

Some other tips

6. Very important, set a time limit

Do not spend 3 days hours trying to fix a bug if you can re-implement the same feature in 2 hours. If you are sure you can rewrite a bug-free version of some buggy code, go ahead with a rewrite and spare yourself the trouble. Time counts.

7 Learn to use tools

Debuggers, memory examination tools and profilers. They will help point out to what might be causing the issue. I once had a really really nasty bug while using jQueryUI, the bug only showed up on a particular browser and only when the page was accessed over the local network; otherwise all was fine.

I eventually had to use a profiler after several failed debugging attempts, I  then discovered that a function was being called several hundred times. Bug case solved!

8. Discuss with a buddy

Find a programmer / buddy to discuss with, discussing your ideas with someone will help you to find design gaps and flawed assumptions; you might be surprised that you get the error spot on without any contribution from your buddy.

Now go ahead and eliminate some bugs :).

The Myth of Perfect Software


Programs do not acquire bugs as people acquire germs, by hanging around other buggy programs. Programmers must insert them… Harlan Mills

Software breaks all the time: booting issues, corrupt software and files, crashes etc; nearly everyone has had a close shave or two with fragile software. Can programmers write ‘perfect’ fault-free software? I presume a trip to Uranus would be much easier, here I come NASA! :D.

A program’s complexity scope is way too large to fit in a programmer’s mind. It is difficult (nigh impossible) to ascertain a program is valid, in fact it is extremely difficult to know the number of errors in software. Here is a simple example, exhaustive validation of an 8 character field would require checking 26^8 combinations (assuming only letters a-z are allowed). Real-life programs contain typically have larger problem domains.

Since achieving a utopia of bug-free software is not feasible, we might as well set our sights on something much more achievable – producing robust software. Robust code doesn’t translate into perfect software; however it tries to behave ‘nicely’ when things go awry – i.e. it does not wipe your hard drive.

Here are a couple of suggestions for writing robust code:

1. Don’t trust anything that comes in from external sources – sanitize, validate and then confirm. You can also log suspicious activity and have default fallback actions.

2. Remember Murphy’s law (“Anything that can go wrong, will go wrong”); that 1 in a 10000000000000000000000000000 chance event needs to be handled even if you ‘think’ it’ll never happen. This is software + humans, remember the large complexity space?

3. It is essential to write simple, flexible, extensible code; if changing one parameter breaks the source then you need to refactor. Also keep in mind the YAGNI principle and do not write unnecessary code just because you feel like it.

5. Write the least amount of (clear) code needed – The less code you have, the less the complexity (and the number of likely bugs/errors) and the better for everyone.

6. Keep cyclomatic complexity low, the fewer the number of executable paths in your program the simpler it is.

7. Test your code and when ‘bad’ things happen, remember to exit gracefully.

Do try to write robust code; you’ll save yourself future worries, impress your customers (which likely translates into lots more $$$ from future referrals) and improve your craft.

This post was motivated by my fascination with the ext file system…. I keep having boot issues with my Ubuntu installation whenever I force it to shut down – this causes the ext file journal system to end up in an unclean state. While in this state, the operating system does not load and I keep ending up at the initramfs prompt. A live disk, some tweaking at the terminal (e2fsck) and the operating system is good as new again.

EmberJS vs Backbone


Although I have never tried out the Backbone framework, I had to review it some time ago when I had to select the JS framework to use. I wrote this last year so if anything has changed please let me know.

EmberJS

Strengths

  • Allows developers to control the entire page at runtime and not just small sections.
  • Two way data binding and computed properties.
  • Auto-updating templates.
  • Reduces the amount of boilerplate code developers have to write.
  • Well-designed framework
  • Better suited to really complex applications
  • Good documentation and really strongly-knit community.

Weaknesses

  • Rigid conventions.
  • Small community.
  • Lacks a data persistence layer although the sophisticated data access library Ember.data (still in development) looks very promising.
  • Quite large ~ 37Kb.

Backbone

Strengths

  • Fast, small and compact – one simple file.
  • Small impact on architecture and/or file layout.
  • Can be embedded in small sections of a webpage.
  • Persistence layer synchronization support over REST.
  • Easier to learn for people who already know jQuery.
  • Strong community and very popular.

Weaknesses

  • Issues with memory management sometimes occur – e.g. zombie views.
  • Users have to write more boilerplate code.
  • Doesn’t scale easily – complexity grows somewhat linearly.

Related

EmberJS: The Rant


So I started on EmberJS some time last year; after spending an inordinate amount of time trying to design a prototype with people located all across the world. Finally, after several dreary demanding iterations and lots of work, we finally agreed on an implementation.

One of the dev members suggested using EmberJS or backbone. Based on his review, backbone was the easier choice: it had more support, good documentation, lots of tutorials, books and thousands of stackoverflow questions (a good measure of  tool/framework/concept popularity).

My own review confirmed these but I stubbornly stuck with EmberJS – I don’t know why, maybe I like challenges or maybe I just wanted to be different. Furthermore, my review revealed a few advantages of using EmberJS over Backbone so I dived into it.

I soon came to regret my decision; after a couple of tutorials, I seemed to be getting no where closer to understanding the framework. The problem was the volatile nature of the EmberJS framework, most tutorials would only work if you used the ‘matching’ framework release. The Ember team was most probably working themselves to the death to get it stable, however, for me, it was challenging, frustrating and annoying to use the framework.

Alhamdulilah I finally got it to work – my first attempt felt ugly and inelegant (add whatever else you like ) but it did work and that was fine enough for me. I soon fell in love with all the extra goodies and automatic help it provided; my colleague was soon inundated by my fawning; most probably he got tired of hearing me say ‘EmberJS is coooooooool’.

Organizing the application proved to be another challenge too; I had a huge ugly proliferation of files – controller, templates, views etc. RequireJS, an AMD loader provided a solution but not before nearly driving me crazy; I inadvertently swapped some parameters in the module specification and had to spent the better part of an hour trying to understand why the login object was a registration object. (Imagine trying to find out why a dog is a cat).

So after weeks of development and finally getting the app nicely running, I got another shocker. There was a new release of EmberJS and guess what? It was not backward compatible! To the credit of the guys though; the new release was awesome, had excellent documentation and was much easier but all I saw was the fact that I’d need to rework everything. All my sweats, efforts and tears were going to go down the drain just like that! No way!! I stuck with the old way and old api – it was much easier for me and upgrades aren’t compulsory.

I have learnt at least two things: one, if you use code that is in rapid flux then you are O.Y.O (ON your OWN) and two, stop testing the waters with your feet, just jump in! If you want to try something new, go get it done!

Back to the story; we did a system redesign again (yes, for the umpteenth time). I believe we are in good shape to do a great job now insha Allaah and yes we are upgrading to the latest EmberJS release – we have some veterans now.

Enough said, I have to get back to work 🙂

For Devs only


I try to do less to achieve more – it is good; it makes me do my job faster and more easily; you should do so too. Automate, use shortcuts, innovate; well the initial investment might take a lot of time but it’s something you will be glad you did.

You can learn a lot by just exploring the tools you use daily. Just try to find a simpler way: some previously unknown feature in your favourite IDE, a macro to allow you repeat a series of actions or just something that saves you some keystrokes. So, I decided to post a couple of tips; I do hope you find them cool and pick up one or two new ideas.

Warning: Some of these work on linux only.

1. Bash Shortcuts

I stumbled upon these while going across someone’s .bashrc file and it stuck me as awesome; yes it is plain awesome. For example, accessing my /var/www/my-web-project folder (and I do access it often) is a pain; why do I have to type cd /var/www/my-web-project all the time? Solution? Just add the following shortcut to your .bashrc:

alias myproj=’cd /var/www/my-web-project’

and that’s it; I just type myproj in bash and am routed to that location. And yes, it doesn’t matter what directory I am in.

2. Bookmarks

Bookmarks are cool, I think they are absolutely essential. Now, if you don’t know how to use them or don’t use them in your IDE/Editor; stop reading and find how to use this wondrous time saver. I use bookmarks a lot in vim and Netbeans (and all other editors if possible); this allows me to jump around and move around. Yes, find out how to use bookmarks and use them!

Talking about vim; I think it’s really awesome and allows you to effortlessly edit anything that is text: I use it for code, latex, writing anything everything. At times, it might be easier to use a less powerful editor however most times, it does all and really cool too. And if you’re a ‘vimmer’, then try out these plugins: nerdtree, nerdcommenter, syntastic and latexbox (if you write in latex).

3. Debugger Statement (JavaScript)

I picked up this while watching an EmberJS tutorial and it has become a major part of my arsenal. Maybe I overuse it (well, I have to write so much JavaScript nowadays). Just put a debugger statement in any part of your JavaScript code and fire up that page in your browser; whenever execution gets to that point, it’ll automatically stop. I use this virtually everytime nowadays and for JavaScript devs; it’s a must use. Another cool JS tip involves using the console object; I use console.log too often but there are a couple of other cool functions like console.trace(), console.dir() etc.

4. Picking an object with a particular Characteristic

I picked up this trick while working in Python on my thesis: I often needed to pick up objects with certain properties out of long lists of objects. The interpreter is essential and this is what I do:

for obj in objectList:

if obj.ppty == criteria:

break

obj

Obj is now equal to my desired object.

5. Testing for -1 (Nice Discovery from SO)

I picked up this explanation from stack overflow and couldn’t help sharing it. I do hope you wouldn’t write code like this but it is always great to gain some insight into how things work.

Assuming you want to test if something is equal to -1; in 2’s complement systems, the representation of -1 is 11111111 (for whatever number of bits the system supports). Just take the bitwise inverse of that number and all you get is zeros. Now for the cool part, zero is a falsy value which can be used in your tests. Here is the link.

Hope you picked up something or the other from this; if you did; do share it with someone who might pick a point or another from it.

Did you like this post? Try out some of my other posts: