Wednesday, May 7, 2014

Idiomatic Code

To create idiomatic code is to create a construct that is natural and appropriate for the context. But what is 'natural' or 'appropriate'? The context helps determine what is 'natural' and 'appropriate' but there is more than a little subjectivity involved in determining what is idiomatic. An extreme example of what would not be natural or appropriate would be to code all your classes in Python to access attributes like a dictionary because you want to access these attributes using strings

class StringAccess(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __getitem__(self,key):
        if key == 'name':
            return self.name
        elif key == 'age':
            return self.age

my_instance = StringAccess("John Doe", 47)

print(my_instance['name'])
print(my_instance['age'])

I have actually seen this done before and because of the overall poor quality of the code it was never clear to me why. It is possibly a pattern brought over from the creator's experience in another language. What leads me to that assumption is that while the overall quality of the Python code was very poor, the code showed signs of the author's deep understanding of advanced programming concepts.

A more idiomatic approach would be to use the 'getattr' function, the use of 'getattr' is idiomatic to Python and would signal to future inspectors and users of your code that you intend to access the members of this object using strings. Rather than this type being a custom implementation of a dictionary.

class StringAccess(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

my_instance = StringAccess("Jane Dow", 38)

print(getattr(my_instance, 'name'))
print(getattr(my_instance, 'age'))

The readability of your code by future users is the principle reason for striving to write idiomatic code. Recently someone said to me, "when you write code at your cleverest often you are not smart enough to debug it." The future user of your code may be yourself, or someone else. This argument should not be used as an excuse to not push the boundaries of your own ability, but to push those boundaries within the context of the technology your are working with. Even the most gifted developers go through a apprentice phase when they are learning a new technology. Often their experience will accelerate their progress, but brining along the assumptions and concepts from experience with previous technologies is something to avoid. There is also an aspect of, "don't reinvent the wheel." Part of learning a language is exploring the languages syntax and platform. Overtime just like moving to a new town, you begin to know where things are, and if you have to go somewhere new your experience navigating your new town will help you. What won't help you is, if you need to go to the dry cleaners for the first time you take a left, right, left and go straight through the light to get there, just like you did when going to the dry cleaners from your old house in the previous town you lived in.

No comments:

Post a Comment