Beautiful Code

What is Beautiful Code?

Take a moment to think about what it means to write beautiful code. I mean it; if this is a question that you've never asked yourself then maybe it's time to evaluate if software development is a career or passion. I'm not saying that you can't be successful as a developer by never having pondered the question. What I'm trying to say is that a pursuit of quality is a hallmark of any craftsman. So, what is beautiful code? Is it fast? Is it code that scales well? Is it concise (i.e. lines of code)? Is it easy to read/ clear? Or is it clever?

Let's be honest. We have all looked at a class, or more commonly, a utility function that does something in an unexpected way. It makes us say, "Damn, that's really clever." Maybe we wonder if we could have been smart enough to come up with that technique, algorithm, or recursive loop. First, let me say that the code that made you pause is most likely a snippet from a white paper, copied from stack exchange, or has been a technique that evolved over time through the experience of an industry (e.g. A* in video games).

I will argue that clever code may make us seem clever to ourselves, but it certainly does not make the code beautiful. Beautiful code is something that does one thing very well: it withstands the test of time by being flexible or having the ability to grow into bigger systems without falling apart or wasting the time of developers. Bottom line: beauty is not in the eye of the beholder; beautiful code is code that emphasizes certain qualities. First, is it easy to understand? Is it easy for others to understand? Will this code be useful in the future? These are some of the questions I ask myself when evaluating code. What I don't ask myself is ... "Is this code clever?" 

The five rules to writing clean code

There are dozens of great programming books that discuss how to write clean code. There are even more software engineers who will preach methodologies. In my experience I have found five simple and practical techniques that continue to hold true regardless if I am writing enterprise systems, small projects, or video games.

  1. DRY
    • The Don't Repeat Yourself principle is one of the simplest and easiest to adapt. There is a formal definition of this principle which can be found in the Pragmatic Programmer. Think of it like this. If you write code that repeats, even a little, stop, think, and refactor. The rule of thumb is to do this on the third time that you see repetition. For me, I usually opt to this immediately after I get something working and before a code commit. Frankly speaking, if you do something twice, you or someone else will do it many times over. Why adapt the principle? It's simple: when common functionality is centralized, refactoring becomes that much easier.
  2. Single Responsibility Principle
    • Like the previous principle, this too has a formal definition. It is the first letter of what are known as SOLID principles. I'll try to cover these in more detail in the future. Unlike the other four principles of SOLID, the Single Responsibility Principle is incredibly practical. When writing a Service, a Module, a Class, and even a function, ask yourself, "What does this thing do?" The answer should always be simple and singular. Giving classes names like manager or calling functions update() is the first sign that their responsibilities are poorly defined. This principle must pair with the next
  3. Naming Conventions
    • There is a lot to discuss about naming conventions: What are the right prefixes or suffixes to use? Should you use verbs and nouns? Should you use domain knowledge? This is not what I want to focus on. Instead, let's talk about self-documenting code. When done right, the requirement of code comments becomes rather moot. So what's the trick? Well there are a few:
      • Pack information into your names
      • Choose specific words. For instance, getting the Size() of an object can mean very different things. Is it the weight, the height, or the memory footprint?
      • Avoid generic names. English is a rich language, and using the thesaurus may raise some eyebrows but increasing our vocabulary is part of the job. Use deliver, dispatch, announce, distribute, or route instead of "send." Use launch, create, begin, open instead of "start."
      • Avoid generic names like tmp and retval. Pack information into your names! Similarly, avoid acronyms.
      • Type out the the entire name, whether it's a function, variable, or a class. Type out everything that is required to capture and define the responsibility that it encompasses. With word completion, there is no excuse for being lazy, and memory constraints are long behind us given our fancy new compilers. In fact, this is the most important takeaway here. If you have to write an entire sentence to describe what your function is doing, then go ahead and do that. If you feel like it really is a sentence, well maybe you should break up the responsibility. Do you see where I'm going with this?
      • Throw away unneeded words. We get so used to writing certain prefixes and suffixes that overtime they lose meaning altogether (e.g. manager). If you need a way to sort or organize your code, please use folders and keep the names tight.
  4. Defining Seams & Managing Cyclomatic Complexity
    • Defining seams is all about separating dependencies in code (more on this later). Essentially, by sticking to the Single Responsibility Principle this should happen naturally. Good seams in your code are the key to writing testable code or "code that is easy to write unit tests for."
    • Cyclomatic Complexity is a lovely term for code that just looks terrible. This is the sort of code that is constantly nested with logical if/else paths that become difficult to trace. Fixing this is very simple: refactor code blocks into functions and make them private. I promise this will do wonders for readability.
  5. Managing Dependencies
    • Generically, a dependency is a relationship between two distinct entities, where one can not perform some function or exist without the other. Think about being financially dependent on someone or by someone. Dependencies are often represented as a graph of nodes with arrows pointing from one box to another on which it might be dependent. There is a term that I am sure you have heard before, and if not, you can quickly visualize the meaning: Spaghetti code! This is code that has interlocked dependencies where finding the beginning and the end is virtually impossible. This is a natural phenomenon of complex systems. The best way to keep dependencies under control is to rely somewhat on Interfaces. An interface is essentially the functionality of a class that you can't instantiate. The idea here is that the Interface, once adopted, can be decoupled from its implementation. Next, we use the stairway pattern to decouple the dependency of multiple concrete classes. It looks something like this. 
The Stairway Pattern

The Stairway Pattern

This might seem like a lot of extra work at first, and it's true that knowing when to create Interfaces is not always obvious. So why bother? The simplest reason is that Interfaces are a contract between classes, and by introducing a small barrier between classes, future refactors become easier and less risky.

TL;DR:

The tips I've provided above are incredibly practical. Nothing I've said is new, but when followed diligently they have resulted in beautiful code. That is to say, beautiful code minimizes the time it would take for someone else to understand it. 

There is no such thing as throw-away code when it comes to production.

January Unlocked

January in Review

I can not stress how powerful the act of writing has been in shaping the month of January for me. The five minute journal, which accounted for my first 30 day challenge, helped me assess my priorities and shed light onto both my strengths and weakness. This has been an experiment in positive psychology, habit building, the quantifiable self, and much more.

For those who are not familiar with the five minute journal I implore you check it out at http://www.fiveminutejournal.com/ and learn more about it, or see an earlier post I had made.

Having completed the 30 day challenge I was pretty thrilled, but I was interested in quantifying the results. So I decided to put together an infographic and get a deeper understanding in numbers ...

It's pretty obvious that one reoccurring theme has been Sam and the days we spent together she was always the first and last thing on my mind. 

Yet January was not without its adversities. I am continuing to search for work satisfaction or rather freedom from work. January marks the first month that my new consulting company, ParaCorp, is operational with a few clients already on the books. This is largely still a work in progress but I'm excited at the prospect of not only additional income but the entrepreneurial spirit that has been rekindled by it. In parallel I am also developing a new product that will take several months to complete and as a result I am finding myself quite frequently frustrated by the overall lack of productivity and/or progress on a day by day basis. 

In conclusion I believe that there are tremendous benefits to sandwiching your day with positive thoughts; yet I was not able to achieve any sense of enlightenment through practice of gratitude. I will stick with the journal until I've used up every last page as it will perfectly complement my new morning practice of mindfulness. 

Resolutions 2015

Why make New Year’s resolutions?

One could argue that you shouldn't wait until midnight of the end of a Gregorian year to instill changes in your life. I’ll admit this is a true statement; you could be a new and better you tomorrow. All you have to do is wish for it and there you are. A new and better you. Of course we all know that isn't how life work; in order to create new habits in our lives or instill any kind of change it takes effort, planning and some degree of self-trickery to change homeostasis. Even so, why the New Year? Well… why not? The fact of the matter is that in order to set a goal, also known as “a dream with a deadline”, we have to set a time scale on achieving it. Otherwise it is nothing more but wishful thinking. That is not to say you couldn't set up daily goals, weekly, or monthly goals (aka 30 day challenges). We cannot forget to take a step back and look at the bigger picture, make sure our boat called Vita remains true to its course.

I have been making resolutions every New Year since before I was a teen. Have I nailed every single one or even most for that matter? No of course not; but I have never been discouraged from making sure to put them on paper.

I begin by reflecting back on the year and try to focus on the few things that I would really like to change about myself. Emphasis is always placed on things that I have control over. A goal such as “getting a better job” isn't always achievable, but a goal such as “be more social” is. Now some people say that goals need to be actionable. Well, they would be correct, but resolutions are more than simple check-boxes. They’re an opportunity for growth and self-improvement.

I’ll begin by saying that in a few months I will be 28 years old. Depending on your own age that may seem as very young or very old. For me, it’s the realization that I am not far from becoming the generation that shapes this world, and frankly it’s about time I got my shit together. Don’t get me wrong I’m doing alright by any standard, in fact better than alright but more than anyone else I know where I fall short. When things are good I overspend, I’ve become complacent, my future is not as clear as it used to be, and I am constantly pulled in hundreds of directions.

1.       This year I will learn to say “no”. I will say “no” to myself when I want to eat that delicious bagel. I will say “no” to alcohol even if I know I can handle it. I will say “no”, so that I can start saying “yes” to the things that really make me happy.

2.       I will focus on saving towards a business by opening up a new savings account called “Start-up” -- Thanks Babe <3

3.       I will stop paying fees. I will stop giving away my money to banks, excessively tipping for service, and paying for any additional charges. The money I save will go towards my own goal or be donated via http://www.donorschoose.org/

Those are the big ones, but things usually don’t stop for me there. I like making checklists too of things I would like to achieve and meticulously planning each month for when and how I will tackle these goals. So here is the rest of my list:

·         Reach $10,000 milestone in the start-up fund

·         Get to 10% body fat by June

·         Eat the same thing for 60 days [challenge]

·         Meditate for 30 days straight [challenge]

·         Score 730 or higher on practice test for a GMAT

·         Take the GMAT

·         Attain at least two professional certifications

·         Establish an internet presence

·         Meet ambitious people who want to change the world

·         Speak at a conference

·         Tutor

·         Hire a GVA to optimize routines

·         Learn to surf in the summer

·         Go Skiing twice in the winter

·         Get a tailored suit/s

·         Publish at least one mobile application

·         Focus on habit building

As you can see this list is less focused and is a result of general brainstorming. My advice is to focus on just one thing every month, and slowly cascade things from the previous months down to the next. For example; if my goal is to look great this summer, then I don’t plan to wait until March to build good work out habits, I’ll start now! More on fitness in another blog post. After 30 days of consistent workouts, I will attempt to start building better habits for drinking water, or possibly improving on sleep, or maybe practice cooking for myself every single week. Only after I build up those habits (which actually take much longer than 30 days to become habits) I will attempt something challenging like eating the same foods for 60 days.

All I am saying is, don’t bite of more than you can chew, and chew slowly. Life isn't a race but a journey.