Programming’s dirty word

Us programmers tend to be a logical, pragmatic bunch. We’re good at choosing the option that is strictly speaking the most practical. And yet, I have yet to hear a programmer ask the question “Will anyone want to work with this?”

And there’s the dirty word: want. Many times, we get so caught up in finding the way that will be the most efficient that we forget why we became programmers. I don’t know about you, the reader, but I became a programmer because it’s fun. The moment I stop enjoying what I do is the moment I stop being a programmer and start being a paid coding monkey.

And here’s the kicker: this rabid focus that we have on the practical isn’t practical. It’s quite idealistic in fact. Looking back, the best projects that I’ve completed aren’t the ones where I had an easy, efficient way out. In fact, they’re frequently projects where I get to try something new out or get my hands dirty discovering better ways to solve old problems. In short, as long as you don’t get too distracted from the task at hand, wants are practical.

Now, I already know what counterarguments I’m going to receive from this post, so let me take a moment to address them:

  • You can’t always get what you want. And you would be absolutely right to make this point. No matter what you do, you’re always going to run into a situation where you have to do something you don’t want to do. However, you don’t completely abandon the idea of life just because you’re going to die at some point. Instead, you focus on living as long and enjoyable a life as you can.
  • You’re putting your own desires ahead of your team’s. I’m certainly not arguing that any individual programmer needs to be able to sabotage the rest of the team just because they want something. It is extremely important that you take what others want into consideration in addition to what you want.
  • Programmers need to focus on building a product, not the code. This sounds like something a Product Manager or startup founder would say. And I would agree with it to a certain point. It’s important to work on a product that’s important to you. However, I’m not a Product Manager or startup founder. I’m a programmer, and product design really makes up about 10% of my overall job (and that’s being generous). The rest of that time is spent coding. And programmers shouldn’t have to apologize for wanting to make that time as pleasant as possible.
  • You’re not being pragmatic. You’re right, I’m not being completely pragmatic, and neither should you. The ideal solution is one that is pragmatic and enjoyable. Given a choice between a pragmatic solution and fun one, you should always choose the pragmatic one. After all, a fun but completely impractical idea will never see the light of day. However, things are rarely so black and white. You have to learn to balance tradeoffs. Such as the tradeoff between practicality and enjoyment.

I suppose the main thing that I’m trying to say here is that what you want is an important consideration in addition to what you need (despite what the Rolling Stones would have you believe).

Persistence is a subset of immutability

Whenever I tell someone I’m working on a persistent data structure
library for Python, I almost always get the same response:
“Persistent means that something is stored across process boundaries.
I think you mean to say immutable data structures.”  In fairness, this
response is understandable.  But it’s not quite right.  I’m going to
address both of the points in the above statement.

Persistent means that something is stored across process boundaries

Did you know that letter can mean a note you send through the mail or a thing you use to make up words?  Did you know that programming can mean writing computer programs or mathematical optimization?  I’m sure if I sat down long enough, I could think of more examples.  The point is that the language we speak is full of ambiguities and whatnot.

Before we consider the computer science meaning of persistence, let’s
look at the common meaning.  If we look at the word persistent in
Merriam-Webster, the first two definitions we run into are:

1 : existing for a long or longer than usual time or continuously: as
a : retained beyond the usual period  b : continuing without change in
function or structure 

The meaning Python programmers tend to think of is the definition in
part a.  That is, a persistent data structure is stored beyond the
usual period (the process’s lifespan).  However, when I talk about a
persistent data structure, I tend to mean the definition in part b.

Going with definition b, we can see that lists for example aren’t persistent:

  1. >>> a = [1,2,3]
  2. >>> b = a
  3. >>> b.append(4)
  4. >>> a
  5. [1, 2, 3, 4]

 

Tuples, however, are a different matter:

  1. >>> a = (1,2,3)
  2. >>> b = a + (4,)
  3. >>> b
  4. (1, 2, 3, 4)
  5. >>> a
  6. (1, 2, 3)

 

Ah, but here’s where the second part of this post comes in.

I think you mean to say immutable data structures

In the case of the tuple, you are correct to say that a tuple is
immutable.  And I’m correct in saying that a tuple is persistent.
Just like I’d be right to say that I own a car while someone else
claims that I own an automobile.  However in both cases, they can’t
quite be used interchangeably.  After all, an automobile isn’t
necessarily a car.  It can be a truck or a van or an SUV.

In the same sense, a persistent data structure is effectively
immutable.  But an immutable data structure isn’t necessarily
persistent.  Let’s consider the definition of both of these words from
wikipedia:

Immutable object

In object-oriented and functional programming, an immutable object is 

an object whose state cannot be modified after it is created. 
Persistent data structure

In computing, a persistent data structure is a data structure which 

always preserves the previous version of itself when it is modified; 

such data structures are effectively immutable, as their operations

do not (visibly) update the structure in-place, but instead always

yield a new updated structure. 
These definitions have a lot of common ground, but there is some
difference between them.  Let’s consider a data structure that is
immutable but not persistent.  Prepare yourself.  This will be
complex.  Ready?

  1. >>> 1
  2. 1

 

Has your mind been blown yet?

In this sense, the number 1 is definitely immutable.  You can’t change
it.  It’s always the number 1.  However, it’s not persistent.  How do
you update the number 1?  No matter what you do, it will always be the
number 1.  Sure, you can get 3 by adding it to 2.  But in a
mathematical sense, that’s not really changing the number 1.

In this sense, the number 1 is atomic.  It simply doesn’t make sense
to modify it.  Heck, you can’t even copy it:

  1. >>> from copy import copy
  2. >>> a = 1
  3. >>> a is copy(a)
  4. True

Conclusion

With this semantic difference in mind, remember that it’s just that:
a semantic difference.  Call them Bob if you want to.  However, bear
in mind that when someone uses the word persistence in this way,
they’re not being inaccurate.

Embrace quirks when working with others

For me, learning to work with people was a two-step process:

  1. Realize that other people are different from me. And I don’t just mean that other people just act differently. I mean they are completely different with different motivations.
  2. Realize that this is actually a good thing.

It seems to me that Derek Sivers has learned the first lesson, but I’m not sure that he’s learned the second. When we realize the first lesson, most of us try to avoid the issue. If people are different, the goal must be to suppress those differences. Unfortunately, people just don’t work that way. David Keirsey would describe this as a Pygmalion Project.

For those of you who aren’t familiar with Roman Mythology, Pygmalion was a sculptor who could not find the perfect woman. Solution? He sculpted one. Venus was touched by this story, so she turned the statue into a real woman.

This is a cute story, but it parallels reality more than we realize. Like Pygmalion, when we encounter someone who’s different our first instinct is to shape them into something that’s the same. Keirsey talks about this as the downfall of many relationships: we go to great lengths to find somebody who is different from us, but then we try to make them into ourselves. Of course Derek shows that one can have a Pygmalion project on themself. If we view ourselves as abnormal, the solution is to be more normal.

This tends to have the effect of lowering one’s self esteem. No matter how hard you try, you can’t make yourself be something you’re not. If you try to suppress your quirks, you will either fail or become a mediocre version of what you perceive as “normal”.

I would argue that not only is it not feasible change peoples’ personalities, it’s not preferable. Your quirks are what make you unique, and they are the reason your coworkers need you. Quirks are different ways of looking at things. Rather than suppress them, learn to appreciate them. Most importantly, become proud of your quirks. Other people may not understand them, and that’s the point.

The only time quirks become problematic is when you turn them into Pygmalion projects. If you expect others to share your quirks, you will quickly run out of friends. However, when you learn to appreciate quirks in yourself and others, you become a better person. You begin to appreciate peoples’ strengths and weaknesses. If you pay attention, you might even discover that the person you thought was incompetent is really just different from you.

The moral of this story: Embrace quirks, but don’t enforce them.

REALLY Caring for Your Introvert

After rereading my last post, I realized that it didn’t really paint introverts in the best light. It makes introverts seem selfish. That’s actually a good thing because that’s how introversion tends to look to extraverts. But that’s not really accurate.

Here’s the funny thing about personality: disputes tend to happen between people when they have opposite ways to do the same thing. Whereas extraverts respect people by integrating their thoughts into the whole, introverts respect people by leaving them alone. They view trying to merge peoples’ thoughts into one big whole as an attempt to “water them down”. Thus, introverts will constantly try to differentiate themselves from the common point of view.

That said, introverts would do well to heed Derek Sivers’s advice that sometimes Persistence is Polite. People aren’t usually as put off by an introvert’s “intrusion” as they imagine them to be.

Thus far, I’ve only focused on applying the concept of introversion and extraversion to how we make decisions. But they also affect perception.

Let’s look at Joel Spolsky. If you look at Spolsky’s famous “Don’t rewrite your software” blog post, you can see that Joel is obviously extraverted when it comes to making decisions. It might be easier to see this if you realize that psychologists refer to extraverted attitudes as “objective” and introverted ones as “subjective”. In other words, extraverts tend to look for the “one true” plan or way of seeing things while introverts will be focused on trying to find a plan or truth that works for them. You can see Spolsky’s extraversion in decision-making when he says things like:

They did it by making the single worst strategic mistake that any software company can make

or

The old mantra build one to throw away is dangerous when applied to large scale commercial applications.

or

But throwing away the whole program is a dangerous folly

Heck, even the title of the blog post (“Things you should never do”) is extraverted. These are all couched in very logical language, but taken together you can see an overarching theme: “There’s one true way to write software, and the only way to figure it out is for everyone to add their little piece of the truth. Here’s mine.”

However if you look, it’s clear that Spolsky also has an introverted side. Consider the following phrases:

The reason is that they think the old code is a mess.

or

The consensus seems to be that the old Netscape code base was really bad. Well, it might have been bad, but, you know what? It worked pretty darn well on an awful lot of real world computer systems.

or

“Well,” they say, “look at this function. It is two pages long! None of this stuff belongs in there! I don’t know what half of these API calls are for.”

You can see that Spolsky has an introverted way of perceiving the world that complements his extraverted decision-making. The hallmark of the introverted attitude is the desire to separate oneself from others. The overarching theme of these phrases is “they see the world like this, but I see the world like this”, which is introverted. That the others are wrong is just a side effect.

Again, even though I’ve pointed out Spolsky’s introverted side and extraverted side, remember that this is still oversimplified. I’ve pointed out what I see as his primary ways of looking at things, but you can see others in the rest of his text.

So how can an extravert get along with an introvert?

  1. Agree to disagree. Extraverts tend to dislike ending a conversation without everyone coming to a consensus. Unless the matter is completely trivial, introverts dislike ending a conversation without having differentiated themselves from the other person somehow. If possible, try to find a happy medium. End the conversation by pointing out things you both agree on (carefully: make sure to couch this with phrases like “It sounds to me like you agree with me on x, y, and z”), but acknowledge that there are areas where you both disagree and that’s ok.
  2. Realize that when an introvert is quiet, that doesn’t mean they don’t respect you. If you need feedback from them, try to do so in a way that is respectful to them. For instance, say something like “Hey, whenever you have a moment can we discuss x?”
  3. Don’t go too far in accepting their worldview. Some people (both introverted and extraverted) might try to take advantage of your desire to connect with other people. Always be skeptical of someone whose judgement of you is dependent upon you giving them (or not giving them) something they want.

Simplism

Every red-faced technical debate that I’ve ever gotten into has almost always devolved into one topic:  is this solution simple or is it complex?  And yet, there’s one alternative that we always forget about: simplism.  Simplism is simplicity’s evil twin, and it can be difficult to tell the two apart.  The difference between the two is that simplicity will grow up to be a successful adult who will make you proud, while simplism will grow up to be in jail, doing drugs, and always borrowing money from you.

Ok, so that analogy is a little bit hokey.  Let’s try looking at the dictionary definitions:

simple – easy to understand, deal with, use, etc.: a simple matter;simple tools.

simplistic – oversimplifying complex problems; making unrealistically simple judgments or analyses

When you do something simplistic, you are essentially sticking your head in the sand. You’re implementing a solution that meets the requirements of some problem that’s much simpler than the one you’re presently facing or will be facing in the future. And it’s always the latter part of the last sentence that gets you. Most people are smart enough to know when a solution doesn’t meet their present needs. But trying to find a solution that will be flexible enough to meet whatever random occurrence should come up in the future is tough.

Some people will tell you to stop right there. You don’t know what’s going to happen in the future, so don’t worry about it. But I think that the sign of truly elegant code is that it can be made to do all sorts of things its original author never dreamed of. There’s no need to contort it to do crazy things because it just works. And before you write that off as over-engineering, stop to think of the bigger picture. Remember: business requirements have a habit of changing suddenly in the most unforeseen ways. To get things done, sometimes you have to be willing to not get them done right this minute. As the Zen of Python says:

Now is better than never.
Although never is often better than right now.

So how do you keep things simple without making them simplistic?

I’ve found exactly one method that reliably makes software simpler without making it simplistic: make the software do less stuff. From a strictly technical standpoint, this is a surefire way to make software that is simple and not simplistic. Of course the business side will insist that you meet the requirements and then some. And they have good reason. I only said that this makes things simpler from a technical perspective. Technical simplicity might be business simplism.

But 9 times out of 10, there’s a way to satisfy both sides if they’re willing to compromise. There’s something to be said for the 90% solution. It does 90% of the things business people want and is 90% perfect for the programmers. The 10% you cut out might not sound like much, but if you cut out the right 10%, you’ve earned your salary along with one of your coworkers’.

So what’s the moral of this story? Before you decide on the solution that seems “simplest”, stop and think. Is it really simple, or is it simplistic?

How to have a side project

If there’s one part of a programmer’s professional development that is harder than it seems, it’s starting a side project. I, for instance, love to program. The funny thing is, that programming is the easiest part of programming (those of you who are true programmers will know what I mean). The hardest part is starting to program and finishing your work.

That said, I do have a few bits of advice for programmers who want to start a side project. If you follow my advice, you probably won’t write the next big thing, nor will you have a side project that will stand out particularly well on your resume. But you’ll probably write something that will make you a better programmer, and that’s the point, isn’t it?

Here’s what I’ve learned about starting a side project:

#1 – Have a good time

This is the first point on here for a reason. And I should hope it’s self explanatory. However, note that there are good reasons for making tradeoffs here. I’ll note them below, but there are some things that shouldn’t be tradeoffs. For instance, don’t make tradeoffs based on how it will look on your resume or what the latest and greatest technology is (not that either of these can’t be fun).

#2 – Learn something

I’ve known some programmers who live by the mantra “I’ll learn it later”. Here’s the problem: later never comes. You’re just going to have to accept the fact that you as a professional need to have some responsibility for your own development. Fortunately, a side project is just the way to take on that learning.

#3 – Make it timeless

Here’s where you may have to make tradeoffs in terms of fun. The most fun things are usually a hassle to maintain. For instance, suppose you write a new twitter client. I can guarantee you that at some point in time, the twitter people will change their API in such a way that will break your code. Granted, this isn’t a big deal if you put a lot of time into it. But that’s the problem: no matter what you do, there’s going to come a point in time in your life that you have something else to spend your time on or otherwise just won’t want to deal with your side project. That’s normal. What you want is something that you can come back to after that time is up.

This is part of the reason why I chose pysistence for my project. Aside from keeping up with language changes, it’s doubtful that functional data structures are ever going to change such that my code will break.

#4 – It doesn’t have to be code

I’d probably say that the blog you’re reading right now is my most rewarding side project. Don’t underestimate the value of doing things that aren’t coding. It’s fashionable to talk about how bad it is to be “all talk and no game”, but the fact of the matter is that reading and writing about programming helps you to solidify some of the ideas that may be forming in your head.

#5 – Make it something you’ll use

This is the last point, but that doesn’t mean it’s not important. If you write something fun, you’ll abandon it as soon as it stops being fun. If you write something useful, you’ll have a reason to keep coming back!

The Rolling Stones were wrong

The people that I work with must sometimes see me as selfish. And who can blame them? If an idea doesn’t excite me, I’m not on board with it. Don’t get me wrong. I understand that sometimes you have to do things you don’t want to do. And when one of those moments hits you, you just have to roll up your sleeves and do what needs to be done.

…but it’s surprising how rare those moments really are. I mean really, which do you find yourself saying more:

  1. “Man. I really want X, but I just can’t do that. There simply isn’t any way to avoid doing Y instead.”
  2. “I really need to get X done, but I keep procrastinating. I need to get my act together.”

Judging by my highly scientific approach of recalling blog postings I’ve seen in the recent past and comments I’ve seen on Hacker News, I’d say that problem #2 is the far more prevalent problem. Now sometimes you do run into a situation where you have to deal with something bad to get something that overrides that badness. But at the end of the day, I don’t run into many moments where I just have to do something I don’t want to do. It just doesn’t happen that often.

Some of you probably still see this attitude as selfish, but I don’t think it is. You do need to focus on others in addition to yourself. But happiness isn’t a zero-sum game. Happiness is more like an infectious disease. A person who is excited will also make others excited. They’ll be giving their team their all. Likewise, a person who just isn’t happy can drag others down.

But in either situation, how often do you run into a person who is successful at something they’re not happy doing?

The Wolf in Sheep’s Clothing

The idea of simplicity has been on my mind a lot recently. I have yet to meet a developer who doesn’t believe in it. So everyone believes in simplicity, shouldn’t we have a lot of simple code? Well, no. The other thing that every developer I’ve ever met agrees with is that there isn’t enough simple code out there. This implies a few possibilities:

  1. Programmers don’t believe in simplicity as much as they claim.
  2. Programmers don’t agree on what simplicity is.
  3. Programmers mistake other things for simplicity.

I ultimately think our situation is a combination of these three things. Numbers 1 and 2 are just the nature of the beast. Sure, everyone wants simple code, but let’s face it: deadlines can make that difficult. And the fact that very few people can define simplicity (and I don’t claim to be one of them) much less agree what it is makes it even harder.

But number 3 is the nasty one. I see it all the time. I’ve even done it myself (I know that’s probably hard for you guys to imagine ;). There’s one thing that I see people confusing with simplicity over and over again: expediency.

In the interest of full disclosure, I think it’s important to note that I haven’t found a good definition of simplicity in the context of software development. But I do know that whatever it is, it isn’t expediency.

Now, business types and “product people” love expediency. And who can blame them? Their job is to make sure a product gets created. Granted, I think they underestimate how important good code is to building a product, but that’s a different subject. Plus, I’m the first person to advocate working smarter rather than harder. I’m not necessarily saying expediency is bad.

The problem is when we confuse simplicity and expediency. Expedient solutions are easy to create. Truly simple solutions are easy to maintain and expand. Sometimes solutions areexpedient (easy to create) and simple (easy to maintain). But more often that not, you have to consider the tradeoffs. Do you create something to meet your immediate needs, or do you create something that will meet your future needs?

All I’m getting at is this: it would be really cool if people said “I don’t think we have time for a solution that simple.” rather than playing the simplicity card for themselves. After all, it would be the truth. And I think it would make sure that you aren’t confusing simplicity with expediency.

Myths about code comments

It seems to me getting good at writing comments is an under-appreciated part of a Programmer’s development. However, I feel that this is a part of programming that’s almost as important as writing code itself. So, here are some of the biggest misconception about comments:

Comments are free

This is an assumption that most of us make at one time or another. Comments aren’t actually executable code, therefore they aren’t maintenance costs, right? As it turns out, this isn’t true. When you update the code that the comment references, you usually have to update the comment as well.

Unfortunately, this myth is actually true most of the time. After enough time staring at a comment, it typically becomes “noise” that you tune out. Thus, comments have a nasty habit of not being up-to-date.

Comments make code more readable

This is by far the most pervasive myth that I’ve encountered. If anything, comments make code less readable. Nine times out of ten, I ignore comments unless I’m stumped. In fact, I’m tempted to make emacs hide all comments unless I explicitly expand them.

Comments don’t make code more readable. They are ways to compensate for code not being readable.

You should comment every function, method, class, and module

How many times have you seen docstrings like this?

 
def get_x(self): 
 """ 
 This method gets x. 
 """ 

This is about as close to being a canonical “bad comment” as you can get, and yet people who should know better still do it. Why? Because they feel that they should document every function or class. The reality is that documenting something that needs no documentation is universally a bad idea.

Code must always be “self documenting”

Most of the myths thus far have been of the “comments are a wholesome, healthy thing variety”. Don’t take this to mean that I feel that comments are bad. The reality of the situation is that the decision of whether to comment is just like most other decisions in programming: it’s about tradeoffs.

In most cases, comments should be viewed as code smells. But remember that code smells aren’t necessarily bad. They’re just hints that something might be bad. And sometimes, removing one code smell adds another one which may or may not be worse.

For instance, would you rather use a one-liner that requires a 3-line comment, or a 10-liner that requires no comments? In most cases, code’s readability suffers more when it’s overly verbose than when it has a high comment to code ratio. Thus, I would choose to write the comment in most cases.

Syntax vs semantics: what’s the difference?

This is a subject that many programmers get confused about.  The difference isn’t really a difficult concept, it’s just that it’s not explained to programmers very frequently.  Let’s consider a snippet of a poem by Jeff Harrison:

know-bodies, devoted we to under-do for you
every Sunday-day of dressy morning, black pond,
sky’s germs, chairs’ ponds – prove it, stain!
us, rain-free & orphaned, we’re living laboratories
This is from Dart Mummy & The Squashed Sphinx.  If you haven’t figured it out, this text is generated by a computer.  And it uses the same techniques that a lot of spammers use.  What’s most interesting about this is that it’s grammatically correct.  For instance, “prove it, stain!” is a perfectly valid English sentence.  The problem is just that it’s meaningless.  Thus, we can say that the above poem is syntactically correct but has no meaning semantically.
Programming languages are similar in concept.  Consider the following Python snippet:
The above code is obviously incorrect.  It uses variables that haven’t been declared yet.  Therefore, it is semantically incorrect.  But it is a syntactically valid Python program.
In the same manner, we can say that these two snippets of code are identical semantically although they definitely have very different syntax:
python
def f(x):
return x + 1
rawplus1.py hosted with ❤ by GitHub
ocaml
let f x = x + 1
rawplus1.ml hosted with ❤ by GitHub
Therefore, we can define these terms like this:
 * syntax – A set of rules for specifying a program
 * semantics – The meaning behind that program