New beginnings : New frontiers


I have been pretty much a JavaScript person mostly for the past four (or is it 5?) years – well ever since I did my internship in 2012. No doubt I really like the language, the ecosystem and the potentials. It’s easy to get so engrossed in the ecosystem – there is never a dearth of things to learn or tools to try out. Quite intellectually stimulating and mind-broadening (provided you can spend the time to learn it well).

JavaScript still looks exciting especially with the upcoming changes (async, await, fetch, ES6). As they say however, the more things change the more they remain the same eh? Personally, I think it is time to check out what happens on the other side – the backend. Advocates say server-side development is ‘easier’ and more stable (yeah, they don’t have 1000 frameworks, build tools, task runners and patterns!).

So why the change? Simple answer: Growth. I want to try something new, expose myself to stimulating challenges and stretch myself. What’s the point of finding cozy places? The goal is to grow, expand and become better. And did I just get these thoughts? No, been on my mind for nearly a year now.

So no more JavaScript? Nope – I enjoy that too much and I still have to finish myangular implementation and descrambler. Nevertheless, I am planning to do more full stack work inshaaha Allaah – expect new topics covering micro-services, scaling huge services, rapid deployment in addition to the staples of programming languages, computer science theory and software engineering.

Let’s go!

The difficult parts of software development


Time for a classic rant again; yeah it’s always good to express thoughts and hear about the feelings of others – a good way to learn.

Lots of people think the most difficult aspects of software development revolve around engineering themes like:

  • Writing elegant pieces of code that are a joy to extend and scale beautifully
  • Crafting brilliant algorithms that can land rockets on small floating platforms (yup, SpaceX, I see you…)
  • Inventing new cryptographic systems (please don’t attempt this at home…)
  • Building and maintaining massively parallel computation systems

Agreed, these are extremely challenging and sometimes it is difficult to find a perfect solution. However, since most of these deal with code and systems, the required skills can be learned and there are usually workarounds available.

There is more to software development than engineering and these other facets can spawn tougher (or even impossible-to-solve) challenges.

Here are three of those difficult areas:

1. Exponential Chaos

The combinatorial complexity of code grows exponentially. It’s well nigh impossible and also futile trying to exercise all possible execution paths of a program. Equivalence class partitioning helps a lot to cut down the test space but invariably, we still miss out on a few.

A single if statement with one condition has two paths – the condition is either true or false. Let’s assign the simple one-condition if check code above a theoretical complexity  value of 1. If that if statement is nested in another if statement, the number of paths explode to 4; ditto for two conditions in the if condition check. Re-using our complexity model, this comes to a value of 2 or so.

Most codebases have loads of conditional branching, loops, multi-threading, various components and what have you. So we can safely our complexity values for such code bases in in the high millions or thereabout. Scary? Not yet.

Now imagine what happens when there are hundreds of developers working in that same codebase and making a few hundred check-ins daily? Maybe the complexity value should sky-rocket to the high billions? Trillions?

Given the rapid rate of change and inherent complexity, how do you ensure that quality is maintained? How do you enforce consistency across large groups? A very difficult problem to solve – there are approaches to mitigate the risk but I do not know of any foolproof method that works all the time. If you know of a way, do let me know.

2. I’ll know what I want when I see it

We all think we know what we want – alas, we typically don’t until we see the finished product. Let’s take the following series of interactions between Ade who wants a new dress and his tailor.

Ade: I want some beautiful dress that fits me, is wearable all year round and casual. I want it in 2 weeks.

Tailor: Aha, so you want something casual that fits you, is wearable all year round and need it in 2 weeks.

Ade: Yup right on point

2 weeks later

Tailor: Here it is! (Beaming proudly)

Ade: (Not impressed); I like the fabric and design. But I don’t like the colour, the sleeve length and it doesn’t fit me quite right. Can you change it to black?

Tailor: here, it is in black

Ade: On second thoughts, black would be too hot, could you change it to brown?

Tailor: here it is in brown

Ade: Great! Could the sleeves be shortened by 2cm?

Tailor: Done

Ade: Hhmm, could you revert the sleeves to their original length? I think I now like the earlier design.

Tailor: Done!! (getting annoyed probably)

Ade: Great! This is becoming awesome, could you please reduce the width of the dress? It’s too wide…

Tailor: @#$@#$@$#!!!

Most people usually don’t have physical products tailor-made to their desires. We go to the store (to meet a car dealer, a tailor or an architect) and choose one of the several options there. We can take a car out for a ride, walk through a building or try on a new dress. This helps a lot as we know if we want that product or not.

In software development, it’s a different story – we want something tailored but we cannot express that need accurately until we see the product. Invariably, our descriptions do not match what we desire. To  restate: it’s highly probable that you wouldn’t like a dress you described in its entirety to a tailor when you try it on.

Figuring out what users actually want is a difficult problem – probably why agile methodologies are popular. Less difficult way? Do the minimum possible thing and allow users to play with it. For example, the tailor could have given Ade a paper dress to evaluate all the styles and all that.

Let’s play a simple game: when you start your next project, make sure you document all user requests, also record every update as you go along. I am pretty sure the new requests will significantly differ from the original one. The end product might be totally different from the initial ask even.

3. No laws – it’s the wild wild west out there

If I release my grip on an apple, I expect it to fall down – why? Gravity of course. Most interactions in the physical world are bound by these models. Imagine that a car manufacturer has to design a new super car for some super-rich guy. Mr-rich-guy asks for the following:

  • Must be drive-able by adults, teenagers and infants
  • Must work on Earth, Venus and Mars
  • Can run perfectly on gas, water or coal

The manufacturer can tell him it’s impossible since the current physical models make it extremely difficult to achieve the three impossible orthogonal requirements; maybe if he wants a movie though…

Let’s go to the world of software; consider the typical AAA game, to capture the largest possible market share, products have to be usable on:

  • Multiple consoles (XBox, PlayStation, Nintendo etc)
  • Other architectures (e.g. 32-bit and 64-bit PCs)
  • Operating systems – Windows, Linux
  • Various frame rates

There are also limitations in software (hardware limits, processors, memory etc) but we often have to build ‘cars’ that can be driven well by people in various age groups living in multiple planets!

The support matrix explodes all the time and generating optimal experiences is an extremely difficult task. In fact, most times, the workaround is to have a limited set of supported platforms.

Alas, it’s the realm of 0s and 1s, so software engineers have to conjure all sort of tricks and contortions to make things work. Maybe some day, cars would run everywhere too…

Conclusion

So apart from the technical challenges, there are a few other just-as-challenging (or even more challenging areas) in software development. These include

  • Ensuring your requirements match hidden customer desires
  • Working to meet various regulations and ensuring proper support across platforms
  • Managing technical debt and reducing risk in heavily changed code bases

Your thoughts?

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.

Influential Books for programmers


I try to read a lot of books. Over the years, my ‘taste’ for books has been refined and some of my criteria are listed below.

Book Impact Scale

  1. Length: The 200 – 300 page range is just about right for a technical book. Longer books contain a lot of fluff and repetition. Sometimes I get the feeling that the author had to meet some minimum page count.
  2. Thought-provoking: I love technical books that challenge the way I think, enable me to see things in alternative light and exercise my ‘thinking’ muscles. Isn’t that the goal for reading after all? To broaden horizons and learn alternative viewpoints.
  3. Inclusion of challenges: I like books that provide practice exercises. This cements the new ideas – it is easy to ‘think’ you already know something when you don’t. Solving a problem is the litmus test for understanding.
  4. Enduring: Every field has its ‘classics’ and they exist for a good reason too. If a 30-year old book is still in print, has lots of good reviews and teaches fundamentals; then chances are high it is a GOOD book. Add bonus points for language-agnostic themes.
  5. Simple: Most books fall short in knowledge delivery by employing obscure terms. This might be due to a misassumption of expected readers’ skill levels. Clear straightforward explanations make for easy reading.

Now, here come the books (listed in no particular order).

1. The Pragmatic Programmer

Excellent read. Medium sized at 352 pages but bursting at the seams with sagely advice. The authors used lots of interesting stories to drive home the points. Some of the lessons that have stuck with me include are:

  • Coincidental programming – you don’t why or how the code ‘works’. If adding that statement makes it ‘work’, then it might also cause bugs you can’t explain.
  • Learning:
    • Learn a new language every year
    • Master a single editor (got me to learn vim)
    • Become a command line expert
  • The broken windows theory – quickly leads to software rot
  • Programming close to the problem domain (SICP book did this too)
  • Being proud of your work – craftsmen are supposed to be proud of their work.
  • Bringing about the change you want
  • Test your software else your users will

Definitely influenced me in a big way and probably due for a reread now.

2. Structure and Interpretation of Computer Programmers (SICP)

A master classic – one for anyone who wants to be a master programmer and has the patience to complete all the exercises. Reading the book without solving the questions would make it difficult to fully absorb the goodness.

The authors painstakingly organized the book – the pages flow so smoothly that the increase in complexity is almost imperceptible. You get exposed to a huge slew of programming paradigms (logic, functional, OOP), build cool stuff (8 queens solver, calculus solve, an interpreter and a compiler) and also learn some CS stuff (streaming, Ackermann functions, Huffman etc).

The biggest change for me is getting to understand that programming is all about solving the right problems using the right abstractions and in a logical and well-ordered manner. Languages don’t matter that much – they are just tools for shaping processes and conveying our thoughts. Java, JavaScript, Python, C, C++ are all beautiful languages. If you don’t know how break down problems, evaluate alternatives and create solution pipelines, then it doesn’t matter what tool you use – the end result may work but wouldn’t be a masterpiece.

Give a master carpenter the minimum tools he needs and he can create something beautiful. Give me a fully stocked wood workshop and while I can craft a table it probably would not come close to what the master did with his limited tools. My table might work but I probably won’t get any appreciation for it. Think this same way about programming.

For example, here is how they explained list reversal:

To reverse a list, just append the first element to the end of the reversed sublist

Be warned though, this is probably a year-long journey but one that you must should undertake. It’s freely available and you can check out my repo of solutions too.

3. Code Complete 2

I had always wanted to read this book but I couldn’t bring myself to do that because it was over 1000 pages long. Finally, I gratefully found a strategy that worked – committing to a 30 min read window daily; mostly on the bus commute home.

The points from the book:

  • Avoid complexity at all costs; software is already difficult so make it as dumb as possible. Again, make it plain simple.
  • Always care about quality regardless of your state in software development
  • Create programming models in your language i.e. try to create domain abstractions in the language; this makes it easier to maintain and express ideas
  • Programs are meant to be read by humans first and then for computers next
  • Being open to other ideas and influences – no need getting stuck to some particular tools
  • Testing styles to ensure code coverage

It is a great book – a bit verbose at times but one that you should read too.

 4. Programming Pearls and more Programming Pearls

A bit old but still readable – it made it obvious how programming had advanced and developers could avoid knowing intricate computer details.

The two books are small and contain a lot of ‘pearls’ that make you think deeply; most revolve around events that happened during the authors’ time at the Bell labs. The coding examples might be outdated but the solid principles in the book aren’t.

For example, a book teaching the basics of motion from the 60s would probably still be applicable today; motion fundamentals haven’t changed much. Same way the author’s approach of problem definition, isolation and iterative improvements can’t be faulted.

Highlights

  • Back of the envelope calculations – made me realize how these axioms could influence the way you program. Now you know why these questions are popular at interviews.
  • Over-engineering a solution might help it cope with unforeseen load
  • Iterative improvement – first solve the problem, then improve the algorithm if needed.
  • Confirm algorithmic correction – it’s very easy to assume your algorithms work when they infact contain bugs.
  • Programming for resource-constrained environments – how do you sort 4 million nodes on a limited memory computer?

5. The Little Schemer + The Reasoned Schemer

The style was nothing like any of the others and I surprisingly found it enjoyable. It flows as a series of questions and answers although readers are encouraged to try before taking a peek at the answers.

The first few chapters were easy to breeze through (coming from a SICP background probably helped too) however things get more interesting from about chapter 9 or thereabout.

  • Provides a ‘formula’ for nailing recursion: fix the base case and then handle the recursive case

Learning recursion is easy, master the first part and then you can learn the remaining parts (pun intended).

  • Good explanation of the Y-combinator – slow build up but still challenging explanation of a hard-to-grasp concept.
  • Covers CS concepts like generators, memoizations, closures, Church encoding, currying, continuation passing and more.

Worthy of mention

1. The Algorithm Design Manual (TADM)

Normally algorithms books are all full of mathematical proofs (really important to understand). However, I like the TADM because it focuses more on applying those algorithms in practical context. The various stories by the author and his humorous quips make it all the more fun too.

2. Eloquent JavaScript

The book that exposed me to functional programming and started the long JS adventure. I always recommend it since it is an excellent beginner book, free (despite its high quality) and is just awesome.

Conclusion

Looking back, it is interesting to see the subliminal influence these books have had on me. I only realized some of these while writing this review.

What are your favorite books and how have they influenced the way you write programs? Share in the comments.

Advice for aspiring programmers


I have made a couple of mistakes over the years and wanted to share those pitfalls so upcoming programmers know what to avoid and what works.

1. Focus

You can’t do everything – I don’t think it is possible for one person to simultaneously be a pro at writing high quality code, network engineering, computer hardware and machine learning.

Some years ago, a much younger and naive me wanted to do everything in software engineering, use several operating systems and know enough about network engineering. Did I succeed at that? No, I just diluted my efforts and wasted loads of time (was fun though…).

Laser-like focus is essential as the field of computing is extremely wide. Decide the field you are interested in, narrow down a learning path and get your hands dirty. For example, if you choose software engineering, you’ll have to select one of three tiers: web/mobile/desktop. Once decided, just work on completing a sample project. The more projects you have under your belt, the better you become and the more learning you do.

2. Dedication

You probably won’t become good enough in one or two years. That learn * in 24 hours book? Gives you a feel for what the language syntax is but there is more than that to mastery. You need to learn language idioms, problem analysis and clean architectural design.

This take time – a lot of time: Norvig put it at 10 years; just like mastery in any other field. It is a long haul so set your mind at it and you should hopefully start seeing results in about 5 years.

3. Consistency

Little drops of water consistently dripping on the same spot can wear down rocks.

The rush of excitement you feel at the beginning is eventually going to wane. Once it becomes a dreary old routine, what will keep you going at it? Consistency and habits can compound in surprising ways.

Assuming you are 1% better each day; after a year; you’ll be about 37 times better. Conversely, if you lose 1% everyday, then after a year you’ll be 0.02 of what you were. This is an extreme example but …

Small incremental progress over a long period of time leads to big increases. For example, a developer that dedicates 25 minutes daily to improving his skills would have spent ~183 hours honing his skills after a year. That’s nearly a month of intense study time. Can you study intensely for one month without burning out?

Can’t afford the 25 mins a day? How many minutes do you spend daily on Facebook? Multiply that by 365 to see where your time is going… Oh.. add in some more hours for games, TV and Twitter too. You see little things add up quickly over long periods of time.

Now once you are consistent, what’s the next step?

4. Seek mastery before moving on

Now that you have focus, the next obvious step is to stick to a path. Frameworks pop up every second in software development but hopping around from one framework to another is ill-advised: you would likely end up as a jack of all frameworks and master of none. I agree and encourage exploratory learning but jumping on every fad bandwagon is going to get you nowhere. Rather, make a strategic choice, stick to it and commit to learning it deeply.

Does this make you less marketable? Afterall, you want to be that guy who knows how to write code in 10,000 languages. Mastering a few increases your worth – you can now charge people more for expertise in your domain. Think of it this way, if you want a dining table masterpiece, what kind of carpenter would you prefer? One that specializes in dining tables or a generalist?

5. Learn the fundamentals

I can’t emphasize this enough. Let’s take a story: EmberJS and AngularJS brought about widespread adoption of 2-way binding across UI interfaces and this in turn triggered the proposal for object.observe as a JavaScript language method. More recently, the new path has been reactive programming and virtual DOM, eliminating the need for observables. You guessed it, object.observe got retired from the language. Now, a counter example, Dijkstra’s algorithm has been around since 1956 and it is still in use after 60 years! Can you beat that?

You have to know algorithms, data structures, operating system fundamentals, caching, Mathematics, etc. These concepts are language agnostic and provide a solid bases for solving new problems. That cool functional reactive somersaulting framework you are harping about today? It may be gone in 10 years. Fundamental CS knowledge? Evergreen, safe investment.

6. Be Humble

There are two things you should keep in mind:

  • There would always be a programmer better than you
  • You probably overestimate your skills

Do you disagree with me? Check out your ranking on the programmer skills matrix. Next, read Micheal Church’s excellent adders analogy. Unless you are already at 2.5+, there is no need to brag about your skills. Instead, quitely keep pushing the limits and some day you hopefully would earn bragging rights.

Humility is a great characteristic to have – there are a ton of things you do not know and need to know. And it takes time to reach the levels others have reached. Even if you think you are a rockstar, people generally appreciate a humble confident programmer who doesn’t rub his ‘magnificence’ into their faces all the time.

Need a yardstick to measure your progress? Periodically check back on both lists to track your progress.

7. Learn how to communicate

Most of software engineering is not about writing code – a large amount of time is spent discussing projects, evaluating designs and interacting with customers. The ability to clearly convey thoughts is one most programmers lack and it is a clear differentiator.

Being able to express yourself means you can get help with problems because you can explain them to others, it also means you can convince people to join your open source project or even adopt your architectural design. All these come from being able to sell yourself and your thoughts.

Communication is not limited to speech only though, writing well is another part. Want to improve? Write more, speak more, volunteer to be a spokesperson – practice makes perfect.

8. Get a mentor & be visible

Stand on the shoulders of giants to see farther. You need to avoid making pitiable mistakes if you can, accelerate your growth and ensure you are on the right path. Great mentors help you grow, introduce you to their networks and provide insightful feedback. They have a lot of experience which you don’t.

Don’t hide under a rock! People should know you for what you do!! Would you buy Microsoft Word if you never heard of it? Seek out peers in the community, interact with them and share ideas. Help one another grow and help influence the community. Being visible makes it easier to find mentors, jobs or even new freelance opportunities. Don’t want to go out? Then create a blog, comment on blogs, release software on Github or participate in fora.

9. Be open

No, your favorite language/IDE/tool is not the best thing since bread and butter. It has its own flaws and strengths.

You can have pretty strong opinions on anything, for example, favorite languages. However what you shouldn’t do is get so tied to some language that you refuse to try out any other language. There would always be situations where your favorite tool doesn’t cut it; in such scenarios, find the best tool and deploy it.

A Toyota Camry can probably carry logs of wood but you are better off moving such with a heavy freight truck.

I used to think I understood recursion until I read SICP; I was forced to write programs without resorting to variables and suddenly, simple toy programs became quite challenging. Exposure to various tools will empower you with various problem solving approaches. This is always a good thing since software engineering is all about solving the right problems.

10. Startups can be overglorified

I think most times, the start-up concept is overglorified – it involves a lot of work, huge risk and great rewards on success. However, the idea that once you make that awesome piece of software, it’ll automatically sell itself is mostly false. That rarely happens.

The saddening part however is that most of us do not know how to deliver good software, talk less of selling software. Yet, they want to run the business. Imagine you handing over a truck on the highway to an unqualified driver who barely knows the ropes. What’s that? A recipe for a crash right? Yup, then why do we do the same with startups?

Software is typically not the critical part of most businesses, rather meeting the user’s need is. You need to learn how to write software first, then learn about business and entrepreneurship – creating a MVP, build-measure-learn cycles, customer interactions, acquisition funnels, maintenance and support, delivery pipelines, execution and meeting competitors. Now, you know this, you can see the bigger picture – the software is not the goal. The business is the goal – the best piece of software that no one uses is a failure.

There is nothing bad with working in an established shop for some time to learn the ropes, creating connections and learning how business is run. You can even start testing the waters and at least you have a safe cushion if things go south.

And that’s it! Did I miss out on anything? Do share your thoughts in the comments or follow me on Twitter.

10 years of programming: Lessons Learnt


I wrote my first program around 2006 or thereabout – it was some toy program for the FORTRAN course at school. Ever since then, I have been given the opportunity to take on more challenging programming tasks. It’s been a heck of a journey for me and I am very grateful for the learning, the mentoring from rockstars and the chance to do exciting work.

Looking back, I have learnt a couple of lessons the hard way and wanted to share some of these so that other engineers know what to avoid. These are my rules of thumb currently (in no particular order). Enjoy and let me know your thoughts in the comments!

1. Write plain simple code

Code is meant to be read by computers. Computers and compilers could care less. So if you are feeling super smart then write in 0s and 1s; otherwise, please write extremely simple code.

When exceptions arise necessitating unorthodox or clever approaches; please do add comments and also create documentation. This would help the poor fellow who’s going to maintain it in the future (most likely you).

But why should we avoid clever code? After all, how else does a programmer show off his cool tricks?

if all you have is a hammer, everything looks like a nail – Abraham Maslow, 1966.

The problems associated with smart code are plenty –

  1. They require a higher level of concentration to understand
  2. They are prone to bugs since the smart fluff can hide bugs
  3. They can nearly always be simplified leading to smaller code and bug footprints

Suppose you have a pounding headache and your doctor orders you to buy any non-steroidal anti-inflammatory drug (NSAID). Imagine trying to decipher what NSAID stands for while coping with the raging headache. Not fun eh… What if the doctor told you to buy Panadol (substitute with Tylenol or Ibuprofen etc.)? That’s the similitude of simple vs smart code.

One way to simplify code is by avoiding surprises and establishing consistent patterns. For example, consistent naming patterns, predictable branching styles or standardized design patterns.

Why does this matter? Well it allows someone else to pick up your code, see the structural pattern and then extend it. There is a common language that everyone understands which makes deviations and buggy approaches easy to spot.

But writing dumb plain code is not so easy; so let’s go on.

2. Make it work then clean it up

While working on Odo, the JavaScript Stream library I wrote last year, I  agonized a lot over getting the perfect style. At times too, I catch myself trying to create a masterpiece at the first attempt.  The truth however is that this doesn’t happen often; maybe if you are Donald Knuth.

Most authors do free-flow writing while trying to get their thoughts together; afterwards, the editing and clean up occurs. Why do you think we have book editors? Coding is similar too; rather than rewrite that 3-line function 20 times, why not get the app working and then start refactoring? It’s much faster and code reviews would help catch coding issues you might have missed (just like editors with books).

Typically I just write and get a feature out, then I take a fine sieve to it. All the rules now come into play: DRY, YAGNI, code simplication etc. I do try my best to make it read like poetry (yes I am serious).

3. Never make the same mistake twice

Yes, once is good enough. Twice is bad.

You shouldn’t be shy of making mistakes, no human is infallible but what should scare you is making the same mistake more than once. Do a retrospective after completing each feature to learn what could have been done better and learn from missteps.

I recently took a long amount of time to implement some core software in an unfamiliar area, why? My initial assumptions about existing data structures were wrong and I found out a while later. It wasn’t so difficult to pivot to the right structures and then I ran into another issue – the helper functions I relied on didn’t behave as I expected they would.

Looking back, I could have written tests earlier (instead of later) to validate expected behaviours and also clarified assumptions with senior engineers. Lesson learnt.

A respected senior engineer explained it thus to me:

Junior developers might take a day to realize they are on a wrong path while senior engineers have enough experience to avoid such drains.

Good judgment comes from experience which involves making mistakes and learning. It’s OK to stumble and make mistakes, but please review each one and learn from that.

4. Know where you want to go

How do you get to China? Start heading east. Once you have a target, it is easier to calibrate your efforts and see if you are moving in the right direction. Unfortunately, most software developers never set goals and then get caught up.

The software engineering profession is remarkable for having rapidly changing and moving targets. Currently, the big areas include cloud computing, security, big data, artificial intelligence and AR/VR. Are your skills stagnating or positioning you to shine?

Having a general blanket target (e.g. I want to be a 10X programmer) doesn’t work; there has to be some specificity to it. So for the one who aspires to be a 10X programmer, the next question would be in what areas do you want to excel? Are there examples of such 10X programmers to copy?

Think again; do you want to extend the frontiers of computer science? Design the next Hadoop? Or author a widely popular book / open source software piece.

Know where you want to go and then start walking.

5. Task Breakdown and Estimation

You are to build a brand new calculator app; your manager wants it delivered as fast as possible. How do you estimate the amount of work required and when it’ll be ready for the customer?

How do you eat an elephant? One bite at a time…

The calculator project can be decomposed into modules like the core engine, the user interface and the data storage mechanism for calculation history. Each component should be broken down into smaller chunks. After breakdown, the engineer typically knows the pieces of work that needs to be done before he completes the project and can start implementing each phase.

This quickly becomes tricky when there are multiple people working on the same project and you need to coordinate integration efforts, release dates and project quality.

Always keep in mind the end goal of shipping the software and prioritize tasks accordingly. You want to maximize your return on investment so pick tasks that move you closer to the end goal.

6. Quality

Nope nope nope, testers shouldn’t find simple bugs in your code. You only want them to find bugs that occur when you press 10 buttons simultaneously while doing one-handed push ups standing upside down.

If you don’t find and fix your bugs; your customers will. And they won’t be happy.

Do the right thing; test the happy path first. Then, verify that there are no monsters lurking in the dark corners. Take some time, maybe 30 minutes, to rigourously exercise the code.

I typically write unit tests while completing the feature. Then once it’s ready, every discovered bug gets its own unit test. This helps to protect against regressions in the future. Aside, those unit tests provide active ‘documentation’ of the behaviour of the software.

Don’t compromise on quality – it’s the sign of good software and a great programmer.

tl;dr?

Have been writing programs for some time, made mistakes and learnt lots of lessons.

Do share your thoughts in the comments – would love to hear them!

The Effective Programmer – 3 tips to maximize impact


Effectiveness, (noun) : the degree to which something is successful in producing a desired result; success.

Over the years, I have tried experiments, read books and watched several talks in a bid to improve my effectiveness. After a series of burnout and recovery cycles, I finally have a 3-pronged approach that seems to serve me well.

1. Learn to estimate well

2. Use the big picture to seek opportunities

3. Continuous Improvement

Lets discuss these three.

1. Estimation – the bane of software development

Reliable coding estimates accurately forecast when feature work will be done. But when is a feature done? Is it when it is code complete? Test complete? Or deployed? Most developers wrongly associate code complete with test completion or deployment ready. This explains arbitrary estimates like: “Oh… I’ll be done in 2 hours”; such estimates typically miss the mark by wide margins due to error compounding. Let’s take a simple bug fix scenario at a fictitious software engineering company.

  • Bug is assigned to developer John SuperSmartz
  • John SuperSmartz reads the bug description, sets up his environment and reproduces it
  • He identifies the cause but does some light investigation to find any related bugs (he’s a good engineer)
  • John designs, implements and verifies the fix
  • Gets code review feedback and then checks in

Any of the intermediate steps can take longer than estimated (e.g. code reviews might expose design flaws, check-ins might be blocked by a bad merge, newer bugs might be discovered in step 3. etc). Without such an explicit breakdown, it becomes difficult to properly give estimates. Don’t you now think the 2-hour estimate is too optimistic?

Personally, I use kanbanFlow (I love their Kanban + pomodoro integration) to decompose work into small achievable 25-minute chunks. For example, I might break down some feature work into 8 pomodoros as follows:

  • Requirements clarification – 1 pomodoro
  • Software design and test scenario planning – 2 pomodoros
  • Coding (+ unit tests) – 3 pomodoros
  • Testing and code reviews – 1 pomodoro
  • Check-in + estimation review – 1 pomodoro

Some of the things I have learnt from using this approach:

  • I grossly underestimate feature work – the good side though is that this planning enables me to improve over time
  • I know when to start looking for help – as soon as a task exceeds its planned estimate, I start considering alternative approaches or seeking the help of a senior technical lead
  • Finally, it enables me to make more accurate forecasts – e.g. I can fix x bugs per week…

2. See the big picture

A man running around in circles covers a lot of distance but has little displacement. In optimal scenarios, distance covered equals displacement while in the worst scenario, it is possible to cover an infinite distance and have a displacement of zero.

Imagine working for several days on a feature and then discovering major design flaws that necessitates a system rewrite; a lot of distance has been covered but there has been little displacement. Working on non-essential low-impact tasks that no one cares about is neither efficient nor effective. Sure they might scratch an itch but always remember that the opportunity cost is quite high; the lost time could have been invested in higher priority tasks with a larger ROI.

Whales periodically surface for air and then get back into the water to do their business; so should engineers periodically verify that priorities align with company’s goals. It’s possible to get carried away by the deluge of never-ending feature requests and bugs fixes; an occasional step back is needed to grasp the whole picture. Here are sample questions to ask:

  • Where are the team’s goals?
  • Does your current work align with company goals?
  • Skills acquisition and obsolescence check
  • Opportunities for improvement?

Personally I try to create 3 to 4 high-impact deliverables at the beginning of each week and then focus on achieving these. Of course, such forecasts rely heavily on productivity estimates.

3. Continuous Improvement

Athletes consistently hold practice sessions even if they don’t want to because it’s essential to staying on top of their game. The same applies to pretty much any human endeavor – a dip in momentum typically leads to some loss in competitive edge. The software engineering field, with its rapidly evolving landscape, is even more demanding – developers have to continuously and relentlessly learn to stay relevant.

Staying relevant requires monitoring industry trends vis-à-vis blogs, conferences and newsletters. There are a ton of resources out there and it’s impossible to follow every single resource, rather it is essential to separate the wheat from the chaff and follow a select high-quality few.

Learning and experimentation with new technologies naturally follows from keeping abreast of developments. A developer might decide to learn more about the software stack his company uses, logic programming or even computer science theory. Even if his interests are totally unrelated to his day-to-day job, independent learning would expose him to new (possibly better) ways of solving problems, broaden his capabilities and might even open up new opportunities. I prefer learning established CS concepts to diving into every new db-data-to-user-moving framework.

Opportunities abound such as learning IDE shortcut keys, terminal commands, automating mundane tasks and so on. Ideally you want to start simple by selecting the area with the highest impact-to-effort ratio and then dedicating a few minutes to it daily. Over time, the benefits start to pay off.

And that’s about it! Do you have other suggestions?

Like this post? Follow me on Twitter here or read some of my top posts.

1. Code is poetry: 5 steps to bulletproof code

2. So you want to become a better programmer

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

Staying Up-to-date : Newsletters and Resources


Software developers and programmers work in one of the most volatile of environments, things evolve fast – API upgrades (which imply code obsolescence :P), new technologies (nodejs is about 4 years old only, yeoman was only released in 2012, Hadoop etc) and the emergence of new language releases and tools.

Programmer have to actively follow new trends to avoid playing catch up with the rapidly changing landscape. Curiosity is a great quality of the programming trade and programmers should ideally itch to learn why things work, how they work and how to improve existing tech.

Here are a couple of resources that I monitor, I enjoy them and I hope they are useful to programmers too.

General

1.  StatusCode

Status code is one of my favourites – it is an eclectic mix of information about software development, programming languages, tools and libraries. There is almost always something to tickle your fancy in the weekly releases, from advice on programming to tooling tips to new developments. Updates are not limited to the expected Java/C/C++ combo, Scala, Haskell, Clojure and others regularly pop up now and then.

2. CodeProject

The concise daily reports on industry and development news is something I look forward to. A quick scan of the mail allows me to quickly get abreast what is trending for that day in the Software development world.

Web Development – JavaScript, HTML5, …

1. JavaScript Weekly

This carefully curated selection of JavaScript-related articles is simply amazing. The weekly updates contain libraries, tools, presentations, tutorials, videos and articles. Did I mention that jobs are advertised too?

If you are a web developer, front-end engineer, JavaScript developer or are just plain interested in JavaScript; then you should try to follow this. At times, the list of ‘goodies’ might be too long however the short descriptions beside each link should make it easy to decide if you are going to check the link or not.

I keep wondering how the curator is able to keep finding new things week after week.

2. A drip of JavaScript

This awesome weekly post on JavaScript usually has a simple description of a single area of JavaScript. Joshua Clanton does a really really beautiful job at explaining things and making them clear with examples.

I have learnt a couple of tricky things about JavaScript from this and gotten a deeper understanding of the language. I wish there were weekly drips of Java and Python too.

Warning: the brief write-ups are usually dense so you have to dedicate some time to understanding it.

3. Ember Weekly

Ok, I write code using EmberJS and this allows me to ‘keep’ my eyes on the project (they seem to update it rapidly), it also allows me to follow the community and see what is happening there. Like others, it includes links to articles, videos/screencasts to watch, code samples as well as the ever-ubiquitous job postings.

4. Node Weekly

Node weekly is new, in fact I think the fourth issue was only published one or two weeks ago. It contains information on the NodeJS paradigm, there are articles to read and code samples to peruse. Some useful libraries and tutorials are sometimes included as well.

5. DailyJS

This has information on some topics in JS and is available daily. Most times I take a cursory glance at the contents and at times I go to the main website to check out information. Oh, they do have a LOT of articles on the website.

6. HTML5 Weekly

This is strictly for web developers and designers; it is a good source of updates about topics like websockets, HTML5, WebGL, CSS3 and browser updates. There are also links to tips and demos of exciting stuff.

Python

Pycoder’s Weekly

Python projects, jobs, news, new developments, articles and possible upcoming events. It is a cool way to keep tabs on developments in the Python community. Yes, it’s only once a week too so you don’t get information overload.

Java

Well, since I rarely program in Java nowadays (just the odd snippet or Android app at times) I do not actively monitor developments in the community. However I still follow these channels:

1. Java Magazine

This is published once a month and is usually a huge nicely designed magazine available online. I particularly enjoy reading about the interviews with industry experts and the puzzles at the end of the magazine are quite nice too – although I can not solve most of them because I lack the necessary Java expertise.

It is also a cool way to catch up with trends in the Java Community.

Ubuntu/Linux

1. Full Circle Magazine

This magazine is published by enthusiasts and usually contains one or two columns I find interesting. It is available on a monthly basis and primarily focuses on the Ubuntu class of operating systems (Kubuntu, Ubuntu, Lubuntu etc). The magazine contains news, tutorials, a QA section, some cartoons and the ‘pimp my desktop’ section (I like).

If you know of some other great resources, please do feel free to share them.