Advertisement
General

Contracts: The Practical Side of Semantics

by

We all recognize that we should be writing semantic code. Maybe, you're even using <section> or <em> correctly, and feel pretty good about yourself. But, are you also considering the implied contract that exists when you code?

Let's imagine that a customer requests a text link, “See More,” which should reveal additional text on the page. <a href="#">see more</a> with a click handler should work perfectly, right? Hey, it looks and functions as requested!

No, it will not always work correctly, as it violates the contract between you and the browser. In particular, I'm referring to the one that says the href attribute must have a value that is a valid URL.

There are practical problems which can arise when violating contracts, and those are much better reasons to write semantic code than things you usually think of when you hear the term, “semantic”.


Popular Arguments for Semantic Code

There are, however, much more practical reasons to care about semantics: contracts.

If you ask an average developer what the value of semantic code, you'll likely hear something along the lines of:

  • It assists the disabled
  • Properly describing code makes it easier for machines to interpret

Both are, unfortunately, very easy to neglect. “Blind people and robots are not the target audience” is too simple of a response, regardless of how misguided or ignorant it might be.

In other cases, you might even hear cyclical reasoning, such as “non-semantic code is bad, because it is not meaningful.” It is such a popular notion to the point that parodies on it have already sprung up around the web!

There are, however, much more practical reasons to care about semantics: contracts.


Usage Contracts

Any time that you use some functionality provided by browser vendors, your programming language, or an API, you are relying on a contract.

On one side of the contract exists a provider of functionality. For example, when you use an <a> tag, browser developers are promising to you that they will provide an easy way for the user of your application to navigate to the specified URL.

As always, however, there's the other side of that contract. The implementer of the functionality promises to use the functionality as specified. As soon as he misuses this functionality, all bets are off - leading to potential failure.

Browser functionality contracts

Let's return to the “See More” example from earlier. In the early days of JavaScript, developers would write their JavaScript using a pseudo protocol, javascript:

<a href="javascript:ShowMore()">See More</a>

Relatively quickly, they began to realize that this approach has at least one practical flaw: the JavaScript code is displayed in the status bar of the browser, which doesn't look professional. The answer to this dilemma was to move the code to an onclick handler, and replace the href attribute with an empty hash identifier, like so:

<a href="#" onclick="ShowMore();return false;">See More</a>

Of course, this didn't solve everything. If ShowMore has an error, return false is never called, and the page is scrolled to the top - certainly not desired behavior.

Today, developers separate their HTML and JavaScript and use proper event prevention techniques:

<a href="#" class="show-more">See More</a>
$('a.show-more').on('click', function(event) {
    event.preventDefault();
    ShowMore();
});

But guess what? There are still plenty of problems with this approach: opening in a new tab, bookmarking or copying the link does not work as the user might expect (especially, if there is a <base> tag on the page), which results in confusion, and possibly, a lost customer.

Notice how all the problems described so far arose from a single fact. Developers have been violating their part of the contract with the browser makers: href attribute must contain a correct URL, but, instead, developers were inserting all kinds of garbage.

If we try to conform to our contract, we must ask ourselves: "Why does the contract not allow us to do what we need?" The answer is simple: we misuse the <a> tag. We only use it, because we want the text “See More” to appear and behave like a link. However, when we use words, such as "look" and "appear," is this not the domain of CSS? Isn't this "See More" link, in reality, just a button? This is easy to implement:

<button type="button" class="link-style show-more">See More</button>
$('button.show-more').on('click', ShowMore);
a, .link-style {
    color: @your-shade-of-blue;
    text-decoration: underline;
}
.link-style {
    font: inherit;
    background: none;
    border: none;
    cursor: pointer;
}

Regardless of how many new ways to interact with links are added to future iterations of the browsers, this approach will continue to work, because we are not violating any contract with the browser. We are using elements to convey their meaning, and, instead of constantly working around new problems, we know that the browser will treat this correctly, as it understands what we want.

Sure, it might require a few extra lines of CSS to reset some of the default button styling. It's worth it! Don't be lazy.

Specifications as contracts

...those who did know the semantics, and knowingly ignored them.

In 2005, a large portion of the web development community learned the hard way that ignoring HTTP requirements is bad. The newly released Google Web Accelerator prefetches URLs on a page to minimize the user’s waiting time on a click.

This wrecked havoc in applications, which ignored HTTP, and put destructive operations behind simple links. And there were many such applications.

The problem did not rest in the hands of the developers who didn't understand the semantics of HTTP methods. No, the problem came from those who did know the semantics, knowingly ignored them, and did not share the knowledge.


Maintenance Contracts

Confusing code is bad!

Contracts also exist between developers. Every time you write a line of code, you make a promise to future developers that it does exactly what it appears to do. In other words, confusing code is bad!

For example, using a filtering function (such as filter in Python) to loop over items is incorrect, because there is an implied contract that filtering functions only modify the list, without having any side effects:

def show(item):
    print(item)

fruits = ['orange', 'apple', 'lemon']

filter(show, fruits)  # Incorrect usage of filter

Instead, use explicit looping over a list:

def show(item):
    print(item)

fruits = ['orange', 'apple', 'lemon']

for fruit in fruits:
    show(fruit)

On the other hand, if you can rely on a contract, it, as a result, allows you to clarify your code. For instance, using array_filter instead of a for loop in PHP to filter items allows other developers to understand what is happening after a single glance:

$incomes = [20, 15, -7, 19];
$profits = array_filter($incomes, function($i){
    return $i > 0;
});

Compare the snippet above to using a for loop:

$incomes = [20, 15, -7, 19];
$profits = [];

foreach ($incomes as $i) {
    if ($i > 0) {
        $profits[] = $i;
    }
}

The second version is worse, not only because it is longer, but also because array_filter provides an expectation. It is clear that $profits is a subset of $incomes. There is no such convention with a generic for loop, which explains why we can't make any assumptions, without first deciphering the internals of the loop.


Writing Properly Semantic Code

How do you distinguish between code that is and isn't semantic? How do you notice these contracts? For the most part, simply asking yourself questions should suffice.

HTML Tags

“I am using an <a> tag and I need to put something in an href attribute. href stores the link target destination. So where does my <a> tag link to?” Nowhere? Well, I can then conclude that I am probably misusing this tag.

Named Functions

“I need to print out the contents of my list in a filter function. Is printing out items part of the filtering process?” Not really. That means I am misusing filter.

Functions That Do Too Much

“I am writing a getFoo method, and need to add some modification code within it. Does modifying state make sense as part of getting foo? Would anyone who simply wants to get foo expect that something else happens?” Likely not!

Separation of Concerns

“I want to add some JavaScript within an HTML onclick attribute. Is this correct?” The file you are modifying is .html, right? Instead, place your JavaScript and CSS within .js and .css files, respectively. Always.

Of course, in many cases, some additional knowledge might be required to properly assess the situation. What matters most is to begin thinking about these things, and to avoid the principle “it (kinda) works, so it is fine enough.” Instead, always ask yourself, "What does the code I am writing actually mean?"


Conclusion

Violating a contract ensures that cooperation will break.

Cooperation always depends on effort from both parties. Most of software development reduces to cooperation: cooperation between hardware manufacturers, system programmers, browser developers, library authors, website developers, and many others. Violating a contract ensures that cooperation will break.

Code semantics is one such contract. Care about it for your own good!


Footnotes

Semantic: The term “semantic” is often misunderstood. In the context of this article, I use the term to distinguish the meaning of the code from the results the code produces. For example, semantic meaning of an <a> tag is representation of a link, while the simple, practical meaning of it is clickable, underlined text.

Strictly speaking, an empty fragment identifier # might be considered valid in this context. This technicality, however, misses the point I make in the article.

Related Posts
  • Web Design
    eCommerce
    Getting Started With Liquid; Shopify's Template LanguageShopify 2 preview
    This tutorial will introduce Liquid, the Shopify template language. We'll look at the benefits of Liquid, discuss how it enables us to pull in and manipulate data from our stores and finally showcase a number of its key features that you will find yourself using daily in your Shopify theme development.Read More…
  • Code
    HTML5
    HTML5: Battery Status APIPdl54 preview image@2x
    The number of people browsing the web using mobile devices grows every day. It's therefore important to optimize websites and web applications to accommodate mobile visitors. The W3C (World Wide Web Consortium) is well aware of this trend and has introduced a number of APIs that help with this challenge. In this article, I will introduce you to one of these APIs, the Battery Status API.Read More…
  • Code
    Theme Development
    Creating a WordPress Theme from Static HTML: Creating an Archive TemplateCreating wordpress theme from html 400
    If you've been working your way through this series, you now have a functioning theme with two page templates. The steps I've demonstrated to this point are: preparing your markup for WordPress converting your HTML to PHP and splitting your file into template files editing the stylesheet and uploading your theme to WordPress adding a loop to your index file adding meta tags, the wp_head hook and the site title and description to your header file adding a navigation menu adding widget areas to the header and sidebar adding widget areas, a colophon and the wp_footer hook to the footer file creating template files for static pages. Read More…
  • Web Design
    UX
    Walk Users Through Your Website With Bootstrap TourTour retina
    When you have a web application which requires some getting used to from your users, a walkthrough of the interface is in order. Creating a walkthrough directly on top of the interface makes things very clear, so that's what we're going to build, using Bootstrap Tour.Read More…
  • Code
    Theme Development
    Creating a WordPress Theme From Static HTML: Adding a LoopCreating wordpress theme from html 400
    In the first three parts of this series, you learned how to prepare static HTML for WordPress and to create a theme by splitting your HTML file into a set of template files and editing the stylesheet. You then uploaded your theme to WordPress and activated it. The theme still isn't displaying any content you add via the WordPress admin however; to do that you need to add a loop to your template files.Read More…
  • Code
    Theme Development
    How to Integrate Bootstrap Navbar Into WordPress ThemeBootstrapd 400
    Have you ever wanted to speed-up the process of theme development? I assume the answer is "yes" and you already know about Bootstrap and use it in mock-ups for development. This raises the question: "How can you integrate Bootstrap components into a WordPress theme?"Read More…