Sunday, January 10, 2016

On the importance of "slowness"

Programmers often end up in certain "tribes," that is, groups of like-minded people who share a common philosophy about programming, read the same types of blogs and books, use similar tools and methodologies, etc. One unfortunate reality of these "tribes" is the effect of "tribalism": i.e. a tendency for members of each tribe to look down on other tribes. It's almost like a mild form a "racism" only among programmers. I've certainly been guilty of this "tribalism" myself, and, if you're a programmer, you have as well.

In an effort to clear away some of this tribalism, I would like to address a cross-tribal criticism that I hear regularly: "Your language is slow!"

Now, to give some context, my day job is to program web applications in Python. Python's a pretty good language. It's not my favorite. But it's also not my least favorite. Like I said, it's a pretty good language. So let it be known that I don't have any particular interest in defending Python and denouncing every criticism against it. But, since Python is a slow language, I hear that criticism a lot. And I want to make sure that we, as programmers, can talk about these criticisms properly and accurately.

First, I'd like to go on record and say that Python is slow. It just is. Now of course there's some room for interpretation, so let me be very clear. "Python" is a general purpose programming language. "Python," the language, is slow. Since I'm talking about programming languages here, then "slow" can only sensibly be taken in the context of other programming languages. Which ones? Well, since we're parsing colloquial speech, I think it's fair and safe to assume that the programming languages in mind are the ones that exist in the same genre as Python, namely general purpose ones used anywhere from the classroom to production-quality software in most software environments. So in the end, here's what I mean by "Python is slow": Among general purpose programming languages, Python generally performs worse in terms of time/space efficiency than a majority of its peers in the same genre of software applications.

Second, I'd like to point out that "slowness" can (and must) always be judged along at least two axes: the could and the should. In other words, when we're talking about the "slowness" of something, we can always ask these two questions (given that "fast" is the opposite of "slow," I'll take the liberty to use both terms):

  1. Is this as fast as it could be?
  2. Is this as fast as it should be?

This distinction is crucial. Here's why.

The question of could has to do with technical/practical abilities. Is my program (written in Python) as fast as it could be? Given our previous discussion, the answer is certainly No. We could have written our application in some other, faster, language, like Java, or C.

But what is important to realize is that the question of could is rarely relevant. Instead, the question of should is almost always the question we are actually asking. Is my program (written in Python) as fast as it should be?

What's interesting here is that the answer to the could question can always be obtained in general and in isolation from any particular problem or need. You can always look for more ways to make your program run more efficiently, and you'll almost always find some. However, the answer to the should question can only be answered within the context of a specific need or demand. In other words, the question of whether or not your program is as fast as it should be can only be answered in a context where the specific requirements and demands have made this value judgment possible.

So "slowness" is only truly meaningful in the context of a specific application. This leads us to our next consideration: To what extent does the speed of your language affect the speed of your specific application? In truth, only you can answer that question. It really depends quite a lot on the application.

The reality is, however, that in a lot of applications the speed of the language is actually a fairly small factor to the speed of the application itself. Take web applications for example. A web application uses dozens of tools and technologies which all contribute to the application's overall speed. These might include the storage/database backend, the number of servers running your code, the amount of parallelization you are utilizing, the kind of persistent storage you're using, how much network bandwidth you have access to, how far away your customers are from your servers, how many customers are using your application simultaneously... Clearly there's a lot more to speed than just the speed of your language!

[As an aside, I'm intentionally avoiding a more nuanced definition of "speed" and "slowness." Those are packed terms. Slow from whose perspective? Throughput versus bandwidth? For the purposes of this article, none of those distinctions are important. The point is, "slowness" is about your application, and your application is about more than just your language.]

So what things are affected by the slowness of a language? I think it still has a lot of impact, but mostly at the business level. Here are some thoughts:

  • Slower languages will tend put pressure on your performance requirements sooner than faster languages. If you have a game plan for that, then you're set.
  • Slower languages may tend to incur more operational costs than faster languages (because you need to run more servers with more complex configurations). Operational costs may still pale in comparison to development costs, but it's good to know what you're working with.
  • Slower languages will tend to require optimization sooner than faster languages. That is, faster languages give you a bigger buffer between initial development costs and future optimization costs. Whether or not this is a good trade-off has everything to do with your particular application and its constraints.
  • Slower languages will tend to run server-side more often than client-side. This is only because it is much easier to scale performance on the server than on the client (it's harder to upgrade a customer's hardware than it is to upgrade your own).

[As another aside, I'm intentionally not making any assertions about the relative development costs of slow languages versus faster ones. It's impossible to make such claims generically. As it regards Python, many claim that Python's slow performance is often justified by it's ability to lower development costs. However, this too can only be determined at an application level and isn't always true. I.e. for many applications, there are languages that offer both better performance and lower development costs than Python would offer.]

So when it's all said and done, "slowness" is not a terribly useful criticism to lob across tribal boundaries. Don't get me wrong, a language's speed does have myriad effects, but it's not something that can count as an indisputable "fault" of a language. Every language offers different pros and cons, and slowness might simply not matter. In fact, it often doesn't.

Monday, October 5, 2015

Haskell IDE Using Atom and Stack

Due to the strength of its type system, Haskell lends itself to a great IDE experience. However, that IDE experience has not been as easy to come by for Haskell as it has been for other languages.

Here's how to setup a decent IDE experience for Haskell using Atom and the new stack build tool.
  1. Get Atom.
  2. Get stack on your PATH. (As of version 0.1.5.0, the 32-bit build is more stable than the 64-bit build.)
  3. Install dependencies via stack install ghc-mod cabal-helper hlint stylish-haskell
  4. The command output will tell you it is installing binaries to a particular folder. Add this path to your PATH or copy the files to somewhere else on your PATH.
  5. Install the ide-haskell Atom package and its dependency packages. At the time of writing, the dependency packages are:

Thursday, October 1, 2015

Kinds of Hard

There are two kinds of "hard" in programming, the "I need to learn more" kind and the "I need to debug more" kind. Both of them start with "Huh? I don't get it." But one of them never comes back. Choose wisely.