Mims H. Wright

Genius

Why I Don't Like Haml

Permalink

When I suggested that Huge move Haml to our blacklist of libraries and plugins that we shouldn't use on projects it got a lot of people upset and wondering why? I wanted to lay out all of my arguments in one place.

In this article, I will go through the pros and cons (IMHO) of Haml.

Haml's Claimed Benefits

Some of the benefits are legitimate and I'll give credit where credit is due. Some are overhyped.

Easy to learn

The learning curve for Haml is very gentle. You can pick it up in about an hour. However, you might need to check back on the documentation now and then.

HTML on the other hand has 0 learning curve since I already know it.

Do more with fewer characters

I can't argue with this. There are about 30-40% fewer characters in Haml code than ERB. I love the fact that I can declare a div with just a class name and no closing tag. Adding tags over and over again is a waste of time.

Haml code takes less time to write. A lot less time!

Yeah, fewer characters, but am I saving time? I actually have never thought of typing time as my bottleneck. Thinking time is the bottleneck! I'm talking about making a page render on IE7, fixing CSS problems, writing client side code, and communicating with my team to make sure we're keeping a general site architecture in mind. If you're able to get 30% more done in a day by switching to Haml that means you're spending too much time banging out templates and not enough time planning.

Besides, if you use an IDE, this time difference is greatly reduced. For example…

  • Plain HTML <div id="foo" class="bar"></div>, 32 keystrokes
  • Haml #foo.bar, 8 keystrokes
  • In SublimeText or TextMate with snippets div(tab)foo(tab)bar, 11 keystrokes

Also, I've actually spent a lot of time reading documentation when I run into an “edge case” like using a <span> tag. This is something that I wouldn't have to do if I was using HTML.

Integrating Ruby code is easy and seamless

Absolutely.

ERB also does this.

Haml enforces best practices

I've heard that Haml exposes code smells by removing crufty tags and enforces best practices making code more uniform. I think the code smell thing is probably true and mostly related to inline Ruby code. Beyond that, I have yet to see a significant benefit.

Sure, the whitespace is uniform. You must indent your code correctly for it to even work. This obliterates a lot of personal style that could be irritating to sticklers. But this seems very superficial when I think about it and Haml does nothing at all to stop you from using the wrong class names, nesting too deeply, stacking too many classes on a tag, using non-semantic markup, etc.

If all I get in the end is pretty whitespace and automatically closed tags I can just use HTML Tidy or a validator.

Haml is beautiful!

The Haml website claims that Haml is “Beautiful”. I agree that many individual lines are much prettier than their markup counterparts. Overall, though, I think there are some readability problems which I'll discuss later.

It more closely ties your markup to your CSS classes

It's true. It's very easy to see how a given tag relates to the CSS.

…And that makes it easier for designers to understand

Just what I need. A designer editing my code who knows CSS but not HTML.

Haml is a good replacement for ERB when building templates where most of the content is injected via Ruby

This seems to be the only use case that makes a lot of sense to me. I mean, you're already bedazzling your front-end with Ruby code. You're not dealing with a lot of multi-line content which Haml sucks at. A lot of the benefits for improving code quality become more aparent in this use case.

Keep in mind that this is not a common use case for our team and many people use Haml as a general replacement for HTML.

Haml's Pitfalls

As I highlighted above, my main complaint with Haml is that it's not doing much for me. It's just swapping one language for another. To contrast this, SASS (specifically SCSS) is a language replacement that adds gobs of functionality that I couldn't live without.

But here are some specific things I don't like about it.

Using Haml requires full knowledge of HTML

Haml doesn't really abstract HTML it just abstracts the syntax of HTML. You still need to understand what all the tags mean, how classes and ids and attributes work, and how to structure your page. It's like shortening logarithm(x) to log x, faster to type but still requires you to understand the math (also, might be confused by lumberjacks).

Requires a compilation step

Haml can not be viewed in a browser. You must cross-compile it to HTML. That requires a compiler to be installed. So for every person who wishes to edit the code, they must download and install and run the compiler. If they do not, their changes will be overwritten or need to be manually integrated back into the source code.

No big deal? Try giving this to a graphic designer or worse your client. Hope they have the right Gems installed!

Inconsistent syntax

At first glance, Haml looks very consistent. However, try and add javascript or styles inline. It's not quite as easy as just whacking in a %script or %style tag. Your Javascript might contain (structural) whitespace! Instead, you need a filter like :javascript or need to do another type of hack to make it work.

Inline tags like <strong> are another gotcha (because why would you ever need to make text bold). They require you to either put the tag on a new line, use a special directive to force the compiler to parse it, use markdown and parse it inline, or just fall back to classic HTML! By the way, this isn't covered in the official documentation.

Doing data attributes is totally weird. You need to do a nested hash within your attribute list!

Native HTML doesn't work

Supposedly, you can copy and paste HTML directly into Haml. This works for single lines but I have yet to get it to work for larger chunks due to whitespace issues.

Whitespace sensitive

Whitespace sensitivity can be awesome at first glance. No more dumb tags, just indent! But whitespace can be tricky. Whitespace is invisible so it's not always obvious when it's incorrect. In practice, it makes for a lousy indicator of structure.

Here are some more reasons why…

  • Let's say I copy some code that uses tabs into code that uses 4 spaces. Haml is borked until you fix it.
  • Let's say I accidentally type two tabs or 3 spaces instead of 4. Haml is borked until you fix it.
  • I lose the chance to be creative with my use of whitespace, supposedly a feature of Haml since it makes code more uniform. But creative whitespace can improve readability and frankly, I don't see an errant space or two as much of a threat.
  • It's easy to get lost. Let's say I start 4 levels deep then code 6 more levels deep then I need to add a new line back where I started. If I wasn't counting, It's not clear where my cursor needs to be. If there were closing tags, I'd have a better idea of where to drop in. Here's what I mean:
Tab Jungle
%body
.main
.navigation
%ul
%li
%a{:href => "http://example.com"}
%strong Buy
%span.blink Now!
%li
%a{:href => "http://example.com"}
%strong Buy
%span.blink Now!
%li
%a{:href => "http://example.com"}
%strong Buy
%span.blink Now!
%li
%a{:href => "http://example.com"}
%strong Buy
%span.blink Now!
%li
%a{:href => "http://example.com"}
%strong Buy
%span.blink Now!
/ Quick. Where does the next child of .main go?

Ruby-style Attribute syntax is a PITA

.foo#bar is less to type <div class="foo" id="bar"></div> but to use Ruby attribute syntax requires typing a lot of weird symbols. <a href="http://example.com"></a> becomes %a{:href => "http://example.com"}. It also feels weird and is tough to read.

To be fair, this is improved in more recent versions of Haml.

Readability suffers

Aside from other readability issues I've mentioned, in Haml it's not uncommon to squash a bunch of text together with no spaces (they break it). Something like:

%ul#link-list.nav-list.unbulleted{:data{:src=>"foo.json"}}

It looks like machine code.

Not a W3C Standard

Isn't everyone supposed to be all about Standards!?

Not every project is Ruby

Then what do you do?

The answer is you get a port. But then, you're not really using Haml anymore, you're using Phamlp or Mint or COBAML or whatever. Those ports aren't perfect (some don't try to be) so even Haml code might not work with them.

Slow

It's not something I can comment on but apparently, Haml is 2.8x slower than erb.

Conclusion

I fully expect to get some comments on small tricks or syntax changes I can make to solve some of these problems. Thanks in advance. But to me, there is a deeper underlying problem which has more to do with the dependency on another new language.

Yeah, I get it guys, HTML sucks! Everyone hates it because tags are a major bummer, man. It's not DRY because you have to type more. It's old.

Well email sucks too. It's old and weird and not DRY. Why don't we switch to Facebook messaging! It's free! It cross-compiles to email. It's not difficult to learn! You don't need to keep typing people's addresses over and over, just use their name.

I realize this is a little bit of a silly analogy but you can see how it relates.

Haml hides us from the truth that web browsers and web developers work in HTML.

Update: Added a follow up post about Emmet.

Comments