My last post discussed techniques I once saw as the height of cleverness but now deem foolish. The truth is: I’m still battling with these coding dilemmas everyday… It seems to be a constant game of cleverness/terseness/speed vs. verbosity/readability.
We’re told to write code for the poor soul who has to maintain it in the future. What nobody tells you is how much knowledge this poor soul has, both about the language and the problem domain. People also say to expect this future maintainer to be an idiot — this will mean you write the most understandable code possible. But again: how much of an idiot is this person?
The fact is: we have a set of unspoken assumptions we tend to make about this mystery future maintainer.
The following are mostly assumptions related to JavaScript syntax. Unexplored assumptions are ‘Design patterns’, ‘OOP’, ‘The problem domain’ etc.
Level 1 maintainer
- Sentient humanoid
- Speaks/Writes English well
- Knows what JavaScript is
- Has programmed before
Level 2 maintainer
- Knows the correct syntax for if, else, for, while, do, throw, function, var …
- Knows about types
- Knows all the types available in JS
- Knows the difference between a statement and an expression
Level 3 maintainer
- Knows about strict vs. non-strict equality operators
- Knows about short-circuiting in logical operators
- Knows the difference between Arrays and array-like Objects
- Knows several ways to cast a value, and ways to implicitly force coercion
- Knows regular expressions to an intermediate level (anchors, alternation, character classes)
Level 4 maintainer
- Knows what a bitwise operator does
- Knows about primitives vs. objects, and wrapped primitives for method calling
- Knows what a closure is
- Knows how properties are resolved via the prototype chain
- Knows the differences between prefix and postfix increment operators
- Knows about variable/function-declaration hoisting
- Knows the exact difference between x==null and x===null
- Knows the difference between function declarations and function expressions
Level 5 maintainer
- Knows how to check types without using typeof or instanceof
- Knows why
new Number(1) != new Number(1)
- Knows regular expressions well (lookarounds, capture vs. no-capture, greed)
- Knows what named function expressions are
- Knows the side effects of bitwise operations in JavaScript
Level 6 maintainer (Eich level)
- Knows what values are returned by all JavaScript operators
- Knows all precedence and associativity of all operators
- Knows where ASI will put semi-colons
- Knows the subtle differences between ES 3.1, 5.1 and 6th Edition draft
*** The above is not exhaustive and is very subjective. I don’t wish to compartmentalize understanding into levels — it’s misleading. I just wanted to somehow portray these assumptions in a clearly understandable way.
I think most devs simply do not consider a future maintainer that is any less capable than themselves, and perhaps this is a problem. If you mark yourself as a maintainer 4.5 then is it fair for you to write in a way that presumes that all future readers of your code are <= 4.5? Is this reasonable?
I suppose it depends on what the code does (e.g. high level MVC sugar vs. low-level 3D rendering) and the people that you’re currently working with, for it is from them that you are likely to draw your estimation of an appropriate maintainer level.
I’m interested to hear other peoples’ opinions on this.
What level do you assume in your future maintainers? How clever does your code get before you deem it reasonable to add a comment or opt for a more explicit and clearer technique?
Thanks for reading! Please share your thoughts with me on Twitter. Have a great day!
I expect them to be capable developers who aren’t too moronic/retarded to lookup things they don’t already know.
I think it makes zero sense to not use a language to its full extent (doesn’t mean using nasty hacks etc) just because some crappy programmer might not understand it.
@TM, And how do you define ‘capable’…? I really don’t think it’s all as black-and-white as your comment suggests. And also, when you say “use a language to its full extent” does that include very subtle side-effects that happen implicitly? Flooring using bitwise operators comes to mind (implicit ToInt32 operation), as does the implicit coercion that happens with non-strict equality operators.
I wish it were as simple as being able to use every subtlety and feature of the language as I like… but I think that entirely misses the point of writing code for the benefit of future maintainers.
I typically only leave comments when understanding why I wrote a block of code is difficult and almost never when what the block is doing is difficult. I expect any future maintainer that doesn’t understand what a block of code does in terms of operations to look up, or figure out somehow, what the code is doing. On the other hand, I feel it can be difficult to discern *why* I had to perform a certain RegExp match, so I might leave a comment for why, but not intentionally explaining *what* the RegExp is looking for (unless the RegExp is very complex, which I try to avoid or break down).
I’ve been taught to comment code without regard to the level of expertise of those who may follow. If a block represents an object or some other unit of contstruction it gets a comment. If a line or function represents novel or perhaps more complex use of a language, it gets a comment.
In practice, I tend to follow the above fairly closely when AS3.0 is involved. For some reason (probably because the common observation is “CSS, oh that’s easy”) I tend to not comment CSS. This in spite of the fact that, I use every CSS coding opportunity to employ techniques and styles that may well have been developed, or been adopted by a browser author, as recently as today.
This post, like others in your blog, has the added bonus of forcing me to rethink and formalise previously unspoken assumptions I held since my own “js adolescence” (you might think I never fully grew out of it since I still declare all the variables at the top of the functions, and to me it makes perfect logical sense – but still.).
To answer your invite to debate, I have in my mind an image of the maintainer which changes according to the average quality of the existing codebase or shop I am working in/for. Apart from the obvious hacks, the switch fallthroughs, the exotic syntax and the intentional code horrors which I always make the object of comment incontinence, I am usually quite restrained: I’ve been lucky enough, at least in recent years, to work in situations where the best maintainers could be taken for granted. Were I to contribute to a project that lives in the wild of the opensource, I would probably be overly defensive and comment the hell out of it.
But! Am I right in this case? It’s pretty obvious what’s wrong with too little comments, but what’s wrong with too many comments? Apart from a tiny risk of strained fingers, there’s the possibility of looking pandering, maybe even patronising… but not much else. Sometimes, a few semi-superfluous comments that explain your train of thought make the code a cinch to understand at a glance by someone who might be the best programmer but, who knows, is not familiar with the codebase yet.
So, I started this very comment thinking there was nothing wrong with my comment style, but I end it thinking that I should probably comment on average more, even in the most comfortable work situation.
I try to make things explicit in many cases. I prefer String(1) over ” + 1 and sometimes, but not always, I’ll even write Number(foo) instead of +foo.
Competent JS devs should know everything up to your Level 4. Anything less than that is asking for trouble. Most devs seem to know JS up to Level 1 or 2 and they manage to get by so maybe I have high expectations.
I try to comment *why* I’m doing something, not *how* I’m doing it (unless, as Sam mentions, there’s a nontrivial RegExp involved). My litmus is that if I find myself writing code “tricky” enough to merit excitedly pointing it out to a coworker, then it’s time to break it down into something more easily digestible; after I’m done bathing in my own smug superiority that is π
I might not get the point of your article, but imho the more readable the code you write the easier it is for anyone coming back to the code, including oneself. And since most of our time is spent reading code, we should simply make code as readable as possible. I think that using magic as we learn it for example in http://www.140byt.es should be avoided in code you want to survive, and not rewritten because it’s too cryptic. (I love 140bytes, but it’s more like a coding dojo.) Even patterns can be made readable, and as I learned myself when I jumped onto Python, it’s awesome to learn on code. But making code cryptic by “hacks” like “+x” which has a readable alternative “parseInt(x)” is counter-productive. And if speed is the issue, I suggest you first find the bottleneck, before you start making source unreadable before hand.
And as I read somewhere “programming is the art to write human-readable code, that happens to be interpreted by a machine” (unfortunately I can’t find the original author of it).
#2cents
Truth be told, I never consider the guy maintaining my code, because I don’t think I’ve ever come across an instance in my professional career where code is “maintained.” It’s either changed or it’s not, and most of the times that I see it being changed is because whoever is reading it at the time thinks it sucks for whatever reason and decides to rewrite it. Make it better (for whom is not specified.)
Thus, the code I write I generally couldn’t care less about the maintainer of it, because I know they’ll either love it or hate it, keep it or rewrite it. Thus, I write code that I’ll understand when trying to comprehend it again a couple of weeks later. If I don’t, the cycle restarts and I start hating my own code, and so it is rewritten.
The “write code for the next guy” mentality is, in my opinion, a waste of time.
I would want 2 things from a maintainer of code I’m using:
1) be a good citizen
2) be a good writer
In JS/DOM land, I think it’s more important for someone to know how to be a good citizen rather than what kind of binding named function expression creates, or what that weird-looking [[DontDelete]] thingie is. This means writing future-proof code, not polluting, not touching host objects, degrading gracefully, using experimenatl features with caution, etc.
For the second part β not being too clever and writing readable code. Code that I’ll be able to read and understand. I would want author to have read “Refactoring” and “Clean Code” and/or understand what well-written code is. Unit tests are a plus, although it’s still hard to come across libraries/scripts that have them.
Just realized you’re talking about _future_ maintainer, while I was talking about “maintainer” of 3-rd party code I’m using π
Don’t assume everyone knows all the language tricks like you do. I think the best way is to establish best practices for a company, everyone may not agree, but everyone will code mostly the same way. I hope I never have to maintain/edit/delete/rewrite code that Marcus Spade wrote (since he doesn’t care about future maintainers). Marcus Spade, did you never have to fix a bug that was really hard because the original coder had some mysterious assumption in their code? Or because you weren’t quite sure of the precedence rules and wished they had put in some extra parentheses?
Dear Juan Mendez,
There’s a very real possibility you’ll never have to deal with my code, ever. I’m fairly certain this won’t have an adverse effect on your life or career, just like it won’t matter much to me either. In fact, I couldn’t really care less. Glad we got that out of the way.
I have never in the span of my career had to fix a bug that was hard to track down β which is what I assume you mean β because the original author had expert knowledge that more often than not comes from years of professional, validated experience. On many occasions have I come across code I didn’t understand. As a more inexperienced developer I often swore over it, but these days I find it curious. It’s like coming across a piece of prose, the meaning of which is yet to be determined. In the end, I generally learn something from it; even if the lesson learned is that the code is incompatible with my palate and thus won’t be something I’ll produce. These days I never lament having to deal with someone else’s code. If I don’t like it, but understand its meaning and can verify the end result (i.e. test it) I’ll quite likely just rewrite it β if I care enough that is. Life is short, my time is probably better spent elsewhere.
My point is that in the end these things are subjective, and it doesn’t matter much in the grand scheme of things. Certainly not if you’re on your own. If you’re part of a team, it’s more important to have the team jell and what you refer to as coding standards and practices will just naturally evolve. At least, that’s the experience I have from working on several successful teams, and even more unsuccessful ones. The latter usually decides to spend time to codify standards and processes; the former just works.
Oh and the name is Marcus Stade β not Spade. Glad we could get that sorted out as well.
As a student,I have been taught to comment the code whether it is really difficult to interpret or not.An expert could grasp it well without a need to even have a look on the comment unlike a beginner one.But as a tutor,I feel the necessity to use a comment to make my students learn and understand the concept and even the smallest nuances in a better way.
I liked the categorization of developers at different levels.I guess a good developer is definitely capable of doing tasks mentioned at level 5.
I guess it depends upon what application/purpose you are writing the code for.I would consider a good developer to write the
explanation in the form of comments in order to leave no room for
ambiguity and confusion as there are many ways a person could
think of,while developing a code.It is considered a good practice if it is to be presented to the students from a teacher or presented as a report to the client from an employee no matter how easy or difficult the code is to perceive.
I agree that for a JS maintainer at level 5 to presume the future
readers at the same level is not fair and justified.Also on few occasions,the people you are working with are not capable enough
to help you draw the estimation of an appropriate maintainer level.For me this topic is very subjective and debatable.
One can write multiple codes for the same programme in context with one’s own point of view to develop the code.I myself have found writing drfferent codes for the same programme when given to me few days after writing the first one.Interestingly both are logically correct but both reflect ideas to construct the code which are not similar to one another.In such cases from a reader’s point of view,a need to put comments feels indispensable in order to comprehend the code and absorb the logic of the maintainer.In a similar fashion,I think it is absolutely uncertain to expect from your colleagues to help you estimate a maintainer level.
First of all,the categorisation of maintainers you made into level 1 to 6 is just spot on.I believe in ‘Practice makes man perfect’.I work as a tutor for training new recruits in various companies and hence deem the beginner as level 1 maintainers who have knowledge and programming skills probably even higher than level-1 but lack in experience and ultimately in confidence too.For such maintainers,I prefer to write comments for every simple and difficult block enabling them to break and fully assimilate the code.As the time progresses,their practice,experience will definitely place them higher than level 1 to at least level 4 or even higher depending upon the expertise,knowledge and the aptitude the person has.Once he reaches that stage,there is absolutely no need to write any comments even if the code is difficult to comprehend.Here the judgement to appraise and estimate the maintainer level is a big task and it can vary person to person.
β Any fool can write code that a computer can understand. Good programmers write code that humans can understand. β – Martin Fowler
I just remember this one while programming. Nothing else.
And speaking about writing comment in code.
“Every time you write a comment, you should grimace and feel the failure of your ability of expression.”
βGood code is its own best documentation. As youβre about to add a comment, ask yourself, βHow can I improve the code so that this comment isnβt needed?ββ
– Steve McConnell
I can see there is a mixed opinion for this topic where few people think writing comments is absolutely necessary while others think it is purely a waste of time,efforts and money.According to me,it completely depends upon one’s profession.If you are a tutor and the student is level one maintainer has absolutely no knowledge or experience,commenting becomes very much necessary which the tutor has to do as it is his job.Similarly,the same practice has to be implemented in case of a new employer,new learner,new client.
But at the same time,I sincerely would emphasis on lessening this practice by the tutor/group leader/high level maintainer in future to allow the beginners to learn,interpret,break code on their own.I am strictly against the ‘spoonfeeding’ and would want to let them use their brain in developing logic,deciphering the code.
It occurs quite a number of times with me when I write a script or a program in the past only to look at it after few weeks or months with no idea what’s going on in the code.The reason is I develope a large structures of complex codes/blocks almost daily with my team and it tends to happen that I myself don’t recollect which logic had I applied for that particular code at that particular time in the past.Though I am confident to break down my own code,I would cite this as a little time consuming process.That time which we could constructively use for developing other blocks if we had included comments,at least for some confusing and complex logic.For me,’Time is Money’ and I can’t afford to waste it.Also one can mention some useful notes in the form of comments for future reference like the reason for choosing that particular logic while there were other options possible for writing that particular code.Also then advantage of using comments for its ability to remove bits of code from execution when you are debugging your scripts,persuade the
maintainers to use it quite often.