Friday, May 31, 2013

A Call for Source Code CSS


I've only recently realized how different my mind is from the other programmers around me.  I see things they do not, and vice versa.  Yet our tools assume that we're all the same.  I believe that the concept of CSS ought to be applied to source code.  Allowing programmers to view source code in different styles would be revolutionary.  Two different minds could look at the same code and see in a style optimal for the way they work. We should decouple function from presentation.

Source code today is still just like it was when we used punched cards: plain ASCII text.  Style and functionality are welded together like a Web site from 1995.  Here's what motivates my thoughts on this topic:

It started with comment number 18 on Bug 654567: “It is ironic that I be the one to say this, but we ought to adopt PEP8 coding standards for all new code in the project. I know someone is going to quote me and I'll never hear the end of it...” Of course, the rest of the team pounced on this and with my assent, PEP 8 became the style rule of Socorro. That was on June 16th of 2011, so we can say that we're coming up on the second anniversary of my fateful proclamation.

So where are we with PEP 8? Has it been a revolution improving our code readability and quality? For most people working on the project, I'd imagine that they'd call it a win.

However, for me, I'd say that PEP 8 has wrecked the readability of the code. This is not an indictment of PEP 8, nor do I want to indict myself.  I'm just disappointed that PEP 8 is suboptimal for me and the way that I read code. Read my previous posting for an idea as to why.

There is one rule in particular that causes trouble: the 79 character per line limit. I think Python is a beautiful language. Eschewing braces to delineate blocks of code gives whitespace semantic meaning. With just a glance, I can understand the structure of a method in written in Python. I know that indentation reflects structure. In a C based language, indentation cannot be trusted, it is the braces that define the structure. I'm really bad at visually matching braces to see the blocks of code.

With a 79 character limit on lines, many Python statements have to be continued onto a second, third or fourth line. This overloads the meaning of whitespace: it means the definition of a code block AND it means a line is too long and had to be continued. I can no longer trust glancing at the code to see its structure. I have to parse to see which meaning the whitespace has.

Here's a typical example below: a literal quote of Python code from the Socorro project. PEP 8 dictates a profusion of whitespace that has nothing to do with code blocks. Most of the indentation is continuation lines. The 'if' statement blocks are lost to my eyes. The details of the individual method calls have been promoted to the same importance as block structure. With that promotion, indentation means two different things and it is not obvious to me at a glance which is which.

def __init__(self, config, quit_check_callback=None):
    super(ElasticSearchCrashStorage, self).__init__(
        config,
        quit_check_callback
    )
    self.transaction = config.transaction_executor_class(
        config,
        self,
        quit_check_callback
    )
    if self.config.elasticsearch_urls:
        self.es = pyelasticsearch.ElasticSearch(
            self.config.elasticsearch_urls,
            timeout=self.config.timeout
        )

        settings_json = open(self.config.elasticsearch_index_settings).read()
        self.index_settings = json.loads(
            settings_json % self.config.elasticsearch_doctype
        )
    else:
        config.logger.warning('elasticsearch crash storage is disabled.')


Below is the same method without the 79 character rule. The code blocks are now instantly recognizable. However, the code is denser, and for some, I'd imagine less readable.  However, for me, I want to see the structure first, if I want to understand the details of the individual method calls, I can pick them out. 


def __init__(self, config, quit_check_callback=None):
    super(ElasticSearchCrashStorage, self).__init__(config, quit_check_callback)
    self.transaction = config.transaction_executor_class(config, self, quit_check_callback)
    if self.config.elasticsearch_urls:
        self.es = pyelasticsearch.ElasticSearch(self.config.elasticsearch_urls, timeout=self.config.timeout)
        settings_json = open(self.config.elasticsearch_index_settings).read()
        self.index_settings = json.loads(settings_json % self.config.elasticsearch_doctype)
    else:
        config.logger.warning('elasticsearch crash storage is disabled.')

Different minds work different ways.  PEP 8 is all about standardizing the look of source code. However, making something clearer for one person is obfuscating for another. For the way my brain works, PEP 8 obfuscates more than it helps.

I'm calling for style sheets for source code.  I want to be able to load that method into my editor and see it styled in the manner that works for me.  If someone else wants to see it in the PEP 8 style, that ought to be an option on the editor.  Our source code should express functionality and functionality alone.  Like the relationship between HTML and CSS, source code style should be left to some presentation layer.

Temple Grandin has a great TedTalk about the diversity in how people's minds work: "The world needs all kinds of minds." I say that software engineering needs all kinds of minds, too.  I believe that building a CSS-like system for source code would open up programming to people that might otherwise be unable to contribute.