Should ruby go the haml route and uses significant whitespaces?

Before I start, let me get something straight: I’m not saying it would be a good or bad idea… I’m just asking the question.
I must say that my first experience with a significant whitespace language was a disaster. The first time I had to use Python was on a server via ssh. I was in a hurry and wanted to monkey patch some buggy script I had installed. So without thinking too much I opened the script with a text editor called nano. The problem is that a TAB in nano produces between 173 and 177 white spaces. Realizing this I decided to refrain from indenting one line or two because it was too ugly and unreadable. Then python told me that I could not do this… and at the time I remember thinking it was unacceptable that a script start to malfunction just because of a few missing whitespaces. Anyway, I spent some long minutes trying to fix a few indentation issues (in nano! I still didn’t realize it was the source of the problem) and it was very tedious. Had I try debugging the python script on my local computer with gedit for example, things would surely have turned out differently.
Then Haml came… and I stayed away
This unpleasant experience I had with Python had a rather negative side effect: It made me completely ignore Haml for a long time, which is sad because it is such a great alternative to erb.
But now I use Haml, and I really like it. Not having to “close my tags” is more satisfying than I thought it would be. I always delight when I realize I was about to write a “- end” tag to close a “- @items.each” loop or something like that. I don’t have to! Less typing, less noise, cleaner, prettier, I love this! Wouldn’t be nice if we could do away with the “end” keyword in ruby as well?
Just to give us an idea, here is how an actual class from the Haml gem would look like if it was written in Significant Whitespace ruby:

class ParseNode < Struct.new(:type, :line, :value, :parent, :children)
  def initialize(*args)
    super
    self.children ||= []
  def inspect
    text = &quot;(#{type} #{value.inspect}&quot;
    children.each {|c| text &lt;&lt; &quot;\n&quot; &lt;&lt; c.inspect.gsub(/^/, &quot;  &quot;)}
    text + &quot;)&quot;

Great, it sill looks like ruby. We just removed some noise to make it even more readable.
Let's convert a longer method, still from the Haml gem, to see how it would look like:

def parse_new_attributes(line)
  line = line.dup
  scanner = StringScanner.new(line)
  last_line = @index
  attributes = {}
  scanner.scan(/\(\s*/)
  loop do
    name, value = parse_new_attribute(scanner)
    break if name.nil?
    if name == false
      text = (Haml::Shared.balance(line, ?(, ?)) || [line]).first
      raise Haml::SyntaxError.new(&quot;Invalid attribute list: #{text.inspect}.&quot;, last_line - 1)
    attributes[name] = value
    scanner.scan(/\s*/)
    if scanner.eos?
      line &lt;&lt; &quot; &quot; &lt;&lt; @next_line.text
      last_line += 1
      next_line
      scanner.scan(/\s*/)
  static_attributes = {}
  dynamic_attributes = &quot;{&quot;
  attributes.each do |name, (type, val)|
    if type == :static
      static_attributes[name] = val
    else
      dynamic_attributes &lt;&lt; inspect_obj(name) &lt;&lt; &quot; =&gt; &quot; &lt;&lt; val &lt;&lt; &quot;,&quot;
  dynamic_attributes &lt;&lt; &quot;}&quot;
  dynamic_attributes = nil if dynamic_attributes == &quot;{}&quot;
  return [static_attributes, dynamic_attributes], scanner.rest, last_line

Well, not bad at all... the only problem is that the loop is quite long and I had to double-check to know if the "static_attributes" statement was part of the loop or right after. This kind of double checking could get on my nerves fast.
I'm still undecided. I dislike end tags but they can clear things up sometimes. Anyway, I guess we probably never see this implemented in ruby. What's your thoughts on significant whitespace languages?

40 thoughts on “Should ruby go the haml route and uses significant whitespaces?

  1. It does make the Haml method example a bit harder to read maybe, but then again that method is far too long and complex anyway IMHO 🙂 It’d be interesting to see whether or not significant whitespace would motivate people to structure code differently.
    One negative effect would result from the fact that from time to time you would want to call a method on the result of a block, e.g. “array.map do |foo| … end.method”, and then you’d have two kinds blocks in the code, those with “end” and those without. Of course you could just mandate brackets for that.

  2. I was not too fond of languages using indentation since I first tried COBOL (or a similar old language that I don’t remember that used indentations to do something I don’t remember). Recently, I tried coffescript and it was salvation. Now, every time that I have to write a “end” or a “}” I just say to myself that there’s such a better way…

  3. I wouldn’t mind it at all. I found it quite easy to adjust to significant whitespace thanks to haml and I kind of miss it. Thankfully coffeescript came up recently. I wouldn’t mind having it in rails (maybe as some config option). For my sinatra projects, I think I’m gonna give Seamless a try.

  4. Ruby already does have significant whitespace. Line breaks (which are a form of white space, right?) indicate the end of a statement. We don’t have to put a semicolon or some other character to indicate the end of a statement.
    Ruby just doesn’t have significant _horizontal_ white space.

  5. Not just no, but Hell No!
    I am aware that many people in the last few years have jumped on the “significant whitespace” bandwagon, but it’s a terrible idea. Fine for those who like it, that is, but extremely nasty for those of use who don’t.
    If you like significant whitespace, then find a pre-compiler plugin or something that lets you do that. Leave the rest of us in peace… we don’t want anything to do with it.

  6. I cannot understand why anyone likes languages where invisible characters (or worse, the difference between individual invisible characters) are significant. They are a barbarous throwback to Fortran.
    To each his own, I guess, but it’s definitely not for me…

  7. I prefer HAML to HTML because it saves a lot of typing and is also better laid out. It forces you to structure your file so that not everything is in one line and you have difficulties to see where something begins or ends.
    You don’t have that much tags in Ruby and I also don’t think anyone is writing more than one command per line. You only would save some “ends” but would have to take care to align the commands correctly. Here I don’t think the advantages are significant enough.

  8. I agree with Vidar… whitespace is the reason I avoid python and haml both. I have yet to see about coffeescript – The overabundance of squigglies and semicolons in javascripts may come out about equal to the pain of whitespace. Having something invisible affect the logic of a program is just horrible to me.

  9. I could swear Matz discussed this possibility on the Ruby ML at one point, suggesting you could have a flag which would enable/disable it as a feature. But I spent about 10 min looking for it, and can’t find it, so maybe I’m wrong.

  10. Well, if the decision was taken to implement significant whitespaces in ruby, I’m not sure that it should be made optional… because seeing how controversial this feature appears to be, it could split the ruby community in 2 groups. I think I would prefer that ruby take a stand for or against SW instead of trying to please everyone.

  11. If you turn warnings on, in at least Ruby 1.9 you’ll get warnings if your indentation is inconsistent. So horizontal whitespace isn’t totally insignificant in Ruby.

  12. No. And here’s why: it forces the programmer to pay attention to every individual line in stead of only to the end of the block.
    I think programming languages should be designed according to what I call the “rule of least attention”. This rule simply is “the most convenient programming language is the one which needs the least attention to details”.
    Now, having to write “end” to end a block is indeed a detail one has to pay attention to. But it’s a detail that occurs with much less frequency than indentation, which, if indentation is significant, you have to pay attention to on /every single line/.
    For the same reason, languages that force you to use an end-of-statement separator, like, say, ‘;’ in C, can be annoying. Most of the time, a statement will be on a line by itself. So, the newline should be the end-of-statement operator, and an escape should be available for the rare cases where your statement doesn’t fit a line.
    And If you find the “many ends” confusing, you can solve that by doing something like this:
    http://gist.github.com/1000089
    Yes, it’s even more verbose. But sometimes verbosity can bring clarity, certainly if it’s a comment. 🙂

  13. This is the same fallacious argument I see from Python fans: “I like X, X has significant whitespace, I also like Y, therefore Y should have significant whitespace”. The most important aspect of haml is that it gets rid of all the angle brackets. It can get away with leaving out explicit ends because its blocks are so small. You might say, people should write smaller blocks in Ruby too, but making large blocks painful to read and refactor is not the way.

  14. Programs should format code, not humans. Significant whitespace means that writing a code beautifier is next to impossible. I just can’t get any work done in those languages.
    For me it would be the end of usable ruby.

  15. HAML is a DSL, and uses convention to reduce what you need to tell it to get something done. Ruby is a general purpose tool, those shortcuts introduce an unwanted additional restriction.
    Why would you confuse the two?

  16. yea, I wish to see that in rails core… If you want your whitespaces go and code python, coffeescript or whatever uses it. Ruby is language with end’s, }’s and other stuff we like.

  17. What the hell are you talking about Julius? Rails core? Did you know that in ruby you can already chain multiple statements on the same line if you separate them with semi-colons?
    Also, I wrote in the post — right at the beginning — that I was only asking the question. I’m not saying that ruby should become a whitespace significant language. I only started a discussion on the issue. No need to become overly defensive.

  18. I know that you can chain statements with semi-colons. I’m just saying that code would be much less readable. ie, method_missing in activerecord base class:
    self.class_eval < attributes) # scoped(:conditions => attributes)
    end # end
    METHOD
    No one could read it if it was oneliner. Also i cannot image dsl in such language with ruby blocks and other nice features

  19. No thanks!!!
    What might be helpful however is being able to label end statements so the parser will give better error reports when one is missing.
    if foo

    end_if
    class X

    end_class
    etc.

  20. Please no…
    I have also battled with the whitespace problem in both Haml and Python. CoffeeScript seems OK for some reason. Maybe because I always thought the { } where hard to look at anyway. But I’ll keep my “end”s thank you.

  21. indentation in python is not a problem if you use a proper text editor. those who dont like whitespace are those who dont know the difference between a hard tab and a soft tab.

  22. I like and want. But too controversial to supplant anything.
    Maybe it can be another file extension like .rbs (‘s’ for spaced). When read, the lexer adds the ends as needed.
    But won’t happen. Guess I’ll have to tolerate the one thing about ruby I don’t like.

  23. I would drop Ruby if it did.
    When I sought out the next great web development platform and discovered Ruby years ago, one high priority item was aesthetic appeal. I can’t stand that certain languages like Python use indentation/whitespace as a means of closing blocks.

  24. If it would be optional it would be fine. And not the default.
    If it would be enforced though, many people would be disgruntled.

  25. Only behind will be the easily accessible Experience-Detect
    and Drive-Mode buttons occupying prime actual-estate.
    It replaces the film that are used in traditional photography.
    Whether selling teddy bears, cell phones or photography, the business
    principles are the same.

Leave a Reply

Your email address will not be published. Required fields are marked *