A Case Against // MARK: Comments

This article uses Swift 2.1.

MARK comments are often recommended as a way to divide a construct (class, enumeration, struct, etc.) into sections of related methods and properties. Here's how such annotated class may look like:

class Movie: Shareable, CustomStringConvertible {

    let title: String
    let cover: UIImage?

    init(title: String, cover: UIImage?) {
        self.title = title
        self.cover = cover
    }

    // MARK: Shareable

    var text: String {
        return "Movie: \(title)"
    }

    var photo: UIImage? {
        return cover
    }

    // MARK: CustomStringConvertible

    var description: String {
        return title
    }
}

Document Items view (Control-6 shortcut) uses MARK comments for a hierarchy it shows:

Document Items view for Movie.swift

At first sight it seems that using MARK comments is a totally good idea, right? I decided to analyze if it really is 🤔. Here are my findings.

It's Just a Comment

Even though Xcode parses MARK comments and uses them when populating Document Items view, they're just glorified comments. Smarter people than me have a thing or two to say about comments in general:

Comments should be clear and concise and avoid unnecessary wordiness. Make sure that comments are kept up to date with the code. Check that comments add to the understanding of the code.

Generally, you want your comments to tell WHAT your code does, not HOW.

To me, MARK comments lie somewhere between WHAT and HOW, but probably closer to HOW.

As with other comments, it's hard to keep them up-to-date during ongoing development. You start with a clean slate, but then, after a couple of months, end up with a total mess. Some files have MARK comments, while others don't. Some of the sections have unrelated methods in them. There's no strictness at all here.

To keep MARK comments in the good condition, you have to remember about them after almost each refactoring you do. I don't like putting this additional burden on myself. Writing code is hard as it is!

I checked some closed- and open-source projects before writing this article. They all had these issues. I'd much rather prefer not having any MARKs at all than this chaos of well and badly annotated code in one project.

False Sense of Tidiness

When you look at files divided into sections, they seem neat. I think, though, that in reality they aren't neat at all. MARK annotations just trick our brains into thinking that the code is well designed and clean.

In most cases the need to put a MARK comment indicates that the file is getting too large. It's the right moment to start thinking about a refactoring. As others have duly noted, this is most often visible in case of view controllers.

I agree with Jason Brennan that it's really important to have a metric for when a construct of code gets too big. If you follow his suggestion of trying to make your classes, structs and enums shorter than 100 LOC you will find out that MARKs aren't needed at all, because your files almost fit on one screen anyway (depending on your screen and font sizes).

Moreover, I'm not familiar of similar ideas for code “organization” in other languages and IDEs. Please correct me here, if I'm wrong.

There are Better Alternatives

We can often see MARK comments used to annotate methods needed for a protocol conformance. It's mostly an Objective-C legacy because in Swift we can put a protocol conformance into an extension. So, our initial example can be written in this style instead:

class Movie {

    let title: String
    let cover: UIImage?

    init(title: String, cover: UIImage?) {
        self.title = title
        self.cover = cover
    }
}

extension Movie: Shareable {

    var text: String {
        return "Movie: \(title)"
    }

    var photo: UIImage? {
        return cover
    }
}

extension Movie: CustomStringConvertible {

    var description: String {
        return title
    }
}

Sadly, Document Items is less helpful than in the initial case – we don't see names of protocols that our class conforms to:

Document Items view for Movie.swift using extensions

It doesn't have to stay this way forever! Radar is our friend here. I encourage you to duplicate my report.

Another example is marking sections of private and public methods. This is just a noise. It's not an accident that Swift comes with public, internal and private access modifiers.

Please note that I'm not against the idea of keeping related methods together. UIViewController's lifecycle methods are a good example of why that makes sense. I just don't see why we should additionally annotate them with a MARK comment.

TODO and FIXME

In contrast, I'm not against using TODO and FIXME comments. They serve their purpose well and are easier to maintain because they're most often placed in the body of a function or a method. It's harder to miss them when making some changes.

One idea 💡 here, though. If you use an issue tracker I highly recommend adding a ticket for that TODO or FIXME. It'll be easier to remember about them when planning work for next iterations.

Summary

We discussed why using MARK comments may not be a good idea after all. I recommend thinking about them as patches, not real solutions for achieving a better designed code. Do you agree?