What’s this programming language?

A couple of weeks ago, I came across the site “What’s that programming language?”, in which you’re shown a snippet of code and you have to identify the programming language.

I looked around to see if there was a way to do the reverse, ie. identify the language, given a snippet of code. Since I have no idea how to actually parse code and do this, I tried doing this using the highlight.js syntax highlighting library. Highlight.js has a highlightAuto() method that can be used as a simple way of doing this.

[See the demo.]

The highlightAuto() method tries to highlight the snippet using all available languages and returns the language for which it identifies most syntactic structures. Obviously, longer code snippets are more likely to be identified.

You can fork the code for the demo on github. Feel free to send in a pull request if you’ve made improvements to the demo. :)

Links

Rubyconf India 2012

I just got back from Pune after attending the third Rubyconf India (well, that was last Monday; I managed to keep this post in drafts for a week), and – having attended all three conferences – I have to say, this conference keeps getting better every year.

For me, the highlights of this year’s Rubyconf were the keynotes by Charles Nutter and Mikel Lindsaar, Matz’s video keynote (obviously) and Steven Deobald’s Clojure talk. Mikel’s talk – How to Win – was especially inspiring and thought-provoking, particularly because I’ve just moved back to the startup world, having joined WowMakers just last month.

Another quite interesting talk was the one about data analysis from Chang Sau Sheong. The audience seemed very enthusiastic in this interactive talk. The talk about mobile platforms was also quite useful, since I’ve been looking at the available options over the past month. Apart from that, Aaron Patterson made a surprise appearance at Rubyconf in a short video message in Rocky Jaiswal and Arun Agarwal’s talk.

Having followed the recent discussion on Pat Shaugnessy’s post about the performance of Ruby strings of less than 23 characters, Niranjan Sarade’s talk about MRI internals was very appropriate for this year’s Rubyconf. I’ve been trying to work through Minero Aoki’s Ruby Hacking Guide and this covered some of the topics from the first few chapters.

One thing I noticed was that (unlike previous years) Rails related talks no longer dominate the conf. Instead, we had more variety in the topics covered, with talks covering JRuby, mobile platforms, data analysis, MRI internals, etc. I guess this is another indication that Ruby adoption is no longer just about Rails.

The inclusion of lightning talks was a great decision this year. There were talks that were interesting, informative and funny. Hopefully we’ll see more of these next year. (Psst… I hear it’s going to be Pune again in 2013.)

Global Day of Code Retreat, Chennai

I spend the day on Saturday at ThoughtWorks Chennai attending a code retreat. This is the first time I’ve attended a code retreat and I had a lot of fun at the event. This code retreat was organized in many different cities across the world as part of the Global Day of Code Retreat (Dec 3).

Code retreat is a day long event where you pair with different people for 45-minute sessions, trying to solve a problem (Conway’s Game of Life) using object oriented principles and test driven development. At the end of each session you delete the code, and start all over again with a different pair.

Session 1. For the first session, I paired with a Python developer but used Ruby and Rspec. Neither of us had spent much time doing test-first development, so we took some time getting used to writing tests before code. My pair didn’t know Ruby, so ping-pong programming didn’t work too well, but Ruby and Python are similar enough for us to not waste too much time on syntax.

We did make the mistake of spending too much time discussing the design in advance; we didn’t write the first few lines of code till almost 10 minutes into the session. At that time, I felt that thinking over the design in detail would help, but I have changed my mind since.

During the discussion after the session, Karthik Sirasanagandla, who was one of the facilitators, pointed out that we were doing TDD all wrong by planning too much in advance. I went through the next couple of sessions slightly skeptical about this idea… Knowing in advance exactly what your class is going to do will only help you write better tests, right?

Session 2. For this session, I paired with a Java developer, and we used Java and JUnit. I have to admit that after using Ruby for a while, statically typed languages seem like a lot less fun and we struggled to get much done.

Session 3. Once again I paired with a Java developer but we used Ruby and Rspec for coding. Rather than me writing all the code we tried another approach to pair programming. I would write some code, and slide the laptop to my pair who would write the next bit of code in Java-ish pseudocode, which I would then rewrite in Ruby, and then explain Ruby syntax. Once again, a lot of time was wasted on discussing syntax rather than on design.

Session 4. After lunch, I paired with another Ruby developer who I knew from the local Ruby user group. Now that language syntax was no longer a distraction, we had a very productive session.

For one, I got rid of the approach I had been using for the first three sessions – using an array of 1′s and 0′s to store the game state. Instead we started with the proper object oriented approach of using a Cell class to represent the state of each cell on the grid. We also switched to Test::Unit and Shoulda for the tests, rather than Rspec that I’d been using in the morning.

Session 5. Most of us were starting to get tired of the constant deleting of the code, and it wasn’t doing morale much good. So instead of having two more 45-minute sessions, we had a single longer session, so that people would have a chance to go further than they had in previous sessions. We also teamed up with our pair from the 4th session. We continued using Ruby but switched to Rspec for testing.

This was the session where I finally started getting the hang of test-first development. Unlike in the previous sessions, this time we strictly followed the principle of having a single failing spec, followed by code to make it pass, and then writing the next spec. We also didn’t spend too much time planning what attributes and methods a class would have and instead focused on what was the next method we needed to add to solve the problem.

Thoughts

One thing that surprised me was the number of developers from enterprise-y companies that turned up. (I too fall into that category.) The fact that very few people were Ruby (and Python) developers was quite surprising, seeing that the event was sponsored by ThoughtWorks and C42, which are both well known companies in the Ruby community.

Another surprise was how many of the people expected this to be some sort of a training session. I had expected most people participating in the code retreat to be people familiar with the format.

Conclusion

I can’t wait for the next chance to participate in a code retreat. It was a great experience pairing with other developers, but I felt that pairing programmers who code in different languages (and completely unfamiliar with each others’ preferred language) leads to time being wasted on understanding the syntax.

For pair programming to be effective, both people really need to code alternately, and therefore need to have at least one language in common. Hopefully there will be more code retreats organized and will have more people familiar with Ruby (or Python or JavaScript).

If there’s a code retreat happening in your city, don’t miss it. You’ll certainly pick up some fresh ideas about object oriented design.

Did you attend a code retreat in any of the cities on Dec 3? How did you feel about the event?

Writing Object Oriented-ish Code in ANSI C

I was trying to choose a language that I could use to practice implementation of different data structures and wanted something object oriented that had a syntax that wouldn’t distract me away from what I’m trying to learn.

Ruby/Python is too high level if you want to learn how to implement as a stack or a queue. Even a simple array can be directly used as a stack or a queue. C++ syntax, for some reason, annoys me, so that too was rejected.

But hey, there’s C. It’s doesn’t technically qualify as an object oriented language, but I could write C code in such a way that it feels like it. Take, for instance, this bit of how you would use a Stack class in Ruby:

s = Stack.new
s.push(10) # s contains [10]
s.push(42) # s contains [10, 42]
puts s.pop # prints '42'

We could write C code that vaguely resembles the structure of the Ruby code (and still get to use pointers!)

Stack s = Stack_create();
Stack_push(s, 10);
Stack_push(s, 42);
printf("%d ", Stack_pop(s));

Now, let’s walk through how we could implement a C structure that behaves like this. First of all we define a struct called STACK. To keep things simple we will limit this stack to integer values only and use a simple array to store the values.

#define MAXSIZE 10

typedef struct STACK {
  int items[MAXSIZE];
  int top;
} STACK;

typedef STACK* Stack;

We have also declared Stack as an alias for a pointer to STACK variables and gotten rid of the annoying asterisks everywhere in our function parameters.

The Stack_create() method should allocate memory for a new stack and return the pointer to it. Also, we’ll write a Stack_destroy() method that will free up the allocated memory once we no longer need the stack. We’ll also add a Stack_isFull() helper function that returns true if we have reached the limit of the array.

Stack Stack_create() {
  Stack s;
  s = (Stack) malloc(sizeof(STACK));
  s->top = 0;
  return(s);
}

void Stack_destroy(Stack s) { free(s); }

int  Stack_isFull (Stack s) { return(s->top >= MAXSIZE); }

Let’s write the Stack_push() and Stack_pop() methods as well:

int Stack_push(Stack s, int item) {
  if(Stack_isFull(s)) return(0); // failed to add
  s->items[s->top] = item;
  return(++(s->top));
}

int Stack_pop(Stack s) {
  (s->top)--;
  return(s->items[s->top]);
}

void Stack_print(Stack s) {
    int i;
    printf("[ ");
    for (i=0; i < s->top; i++) printf("%d ",s->items[i]);
    printf("]\n");
}

Here we’ve also added a Stack_print helper method to print the content of the stack. We can now test these methods in main():

int main() {
  Stack s = Stack_create();
  Stack_print(s);
  Stack_push(s, 10);
  Stack_print(s);
  Stack_push(s, 42);
  Stack_print(s);
  printf("Pop -> %d \n", Stack_pop(s));
  printf("Pop -> %d \n", Stack_pop(s));

  return 0;
}

The output looks like:

$ ./a.out
[ ]
[ 10 ]
[ 10 42 ]
Pop -> 42
Pop -> 10 

In less than 40 lines of code, we have described a naive stack implementation. We don’t get most of the features of real object oriented languages, but the code does feel easier to write this way. I’m not sure how well this approach translates for large projects, but for learning data structure concepts, this is working extremely well for me.

If you want to take a serious look at object orientation in C, this book on object oriented programming in ANSI C [PDF] is a great way to get started.

A gist containing the above code is available here.

Leave me alone when I’m coding

Recently, Roy Bahat, president of IGN Entertainment, wrote about why he’s learning to code. This part of his post, coming from someone who isn’t a programmer by profession, was especially insightful:

Every time I open my editor, I’m reminded that I can’t just “jump in for a few minutes” the way I can with my usual work – either because coding isn’t like that, or because I’m not good enough yet. It takes me time to rev up, remember what I was supposed to be doing and how it fits together.

How often have you had to explain to someone who isn’t a programmer that you can’t just dive in and start coding right away? That it takes some time for you to settle down with the program and become really productive? That a single 3-hour stretch of uninterrupted coding could never be substituted by three one-hour blocks separated by meetings?

I wish everyone who enters software industry – in non-programming roles – would understand the fact that a programmer’s day isn’t neatly split into neat 60-minute blocks in Microsoft Outlook calendar. The only way they could understand is if they tried writing some code of their own. Sadly, I don’t think that’s going to happen in most software companies.


PS. I just noticed another great article on Roy’s blog on the same topic: Learning to code might become a basic job requirement. Do read it.

Paul Graham has written an article about the same topic – Maker’s Schedule.

Writing Ruby Gems – Part 4: Setting up Test::Unit

[This is the 4th part of a series of posts about writing a Ruby gem. The introductory post about this tutorial contains links to each part of the tutorial. Previous post - Publishing to Rubygems.org.]

So far in this tutorial we haven’t written any code that would be useful in solving Sudoku. The reason is that I didn’t want to start writing any code until we have a test framework set up for testing our code.

Test::Unit is the unit testing framework that ships with Ruby, so we will first set up our gem to run unit tests with the “rake test” command. However, I prefer another testing framework, Rspec, for writing the tests. (We’ll set up Rspec in the next part of the tutorial and then continue using that rather than Test::Unit for testing.)

We will write a simple method in the sudoku module that will return a string “Sudoku: version 0.0.0” (the version number will obviously have to be taken from lib/sudoku/version.rb).

We will put all our unit tests in a directory called test. We will now add a rake task called “test” to run all the unit tests. To create this, we will first need to create a Rakefile that looks like this:

require 'rake/testtask'

Rake::TestTask.new do |t|
 t.libs << 'test'
end

desc "Run tests"
task :default => :test

Rake already provides a task called test, so we are making use of that and have configured the task to use the test/ directory with t.libs << 'test'. We will also configure rake to make the test task the default when rake is run. Running “rake” without a task name would now be the same as running “rake test”. (In the next post, we’ll change this to run our Rspec specs rather than the unit tests.)

Now let’s add a test file test/test_sudoku.rb and add a silly test that we know will fail.

require 'test/unit'
require 'sudoku'

class TestSudoku < Test::Unit::TestCase
  def test_silly_example
    assert_equal 2+2, 5
  end
end

2+2 isn’t equal to 5, so this test should fail. Run the rake task:

$ rake test
Loaded suite /home/nithin/.rvm/gems/ruby-1.9.2-p180/gems/rake-0.9.2/lib/rake/rake_test_loader
Started
F
Finished in 0.000950 seconds.

 1) Failure:
test_silly_example(TestSudoku) [/home/nithin/work/sudoku/test/test_sudoku.rb:7]:
<4> expected but was <5>.

1 tests, 1 assertions, 1 failures, 0 errors, 0 skips

Test run options: --seed 21001
rake aborted!
Command failed with status (1): [/home/nithin/.rvm/rubies/ruby-1.9.2-p180/b...]

Tasks: TOP => test
(See full trace by running task with --trace)

Now change the assertion to make the the test pass.

$ rake test
Loaded suite /home/user/.rvm/gems/ruby-1.9.2-p180/gems/rake-0.9.2/lib/rake/rake_test_loader
Started
.
Finished in 0.000544 seconds.

1 tests, 1 assertions, 0 failures, 0 errors, 0 skips

Test run options: --seed 23369

If you try running rake without the task name, you will see that the output is exactly the same.

Now let’s remove the silly test and write a test that acually tests the version_string method that we’re adding.

  def test_version_string
    assert_equal Sudoku.version_string, "Sudoku version #{Sudoku::VERSION}"
  end

Now if you run rake you will get an error with the message: “NameError: uninitialized constant TestSudoku::Sudoku”. To fix this, we need to add the code for the version_string method in lib/sudoku.rb.

require 'sudoku/version'

module Sudoku
  def self.version_string
    "Sudoku version #{Sudoku::VERSION}"
  end
end

Now rake will run the test successfully. Let’s rebuild our gem and install it with the generated sudoku-0.0.0.gem file to see that it installs correctly.

However, we’re not done yet. If you check the gem directory in the gem installation path, you will see that our test/ directory is missing. To tell rubygems to include that code in the package, we’ll add the following line in the gemspec:

Gem::Specification.new do |s|
  # other stuff
  s.test_files  = Dir.glob("test/**/*.rb")
end

Rebuild and install the gem again and you’ll see the test directory in the installed gem path.

In the next part of the tutorial we’ll set up rspec for testing the gem and along with that start adding some real code for the sudoku solver.

[Subscribe to this blog to find out when the next part of this tutorial is published, or keep an eye on the first post in this series where I'll post the links to all published posts.]

Writing Ruby Gems – Part 2: Adding some code

[This is a part of a series of posts about writing a Ruby gem. The introductory post about this tutorial contains links to each part of the tutorial. Previous post - Gem specifications.]

In the previous post, we saw how to set up the gemspec and also installed the empty gem into our rubygems directory. Now it’s time we started adding some code to our gem.

Create a directory called lib/ and save a file sudoku.rb with the following code:

module Sudoku
 # hopefully someday this module will solve Sudoku.
end

It’s not much code, and it doesn’t do much, but we have to start somewhere. Now build and install the gem as we did in the previous part of this tutorial:

$ gem build sudoku.gemspec
$ gem install sudoku-0.0.0.gem

If you check the installation path for your gem in the rubygems folder, you will still find it empty. This is because rubygems doesn’t know what files to package into our gem. To fix that, let’s tell the gemspec what files need to be added.

Gem::Specification.new do |s|
 # rest of the stuff
 s.files = Dir.glob(“lib/**/*.rb”)
end

Build and install the gem again, and this time you’ll find lib/sudoku.rb in the gem installation directory.

Gem authors often use a version.rb file to store the version information. It’s always prudent to use a separate directory within the lib directory to put your code. This is because require 'yourgem' causes rubygems to add your gem’s lib/ to the load path. Now every require statement will also look at the files in your lib/ and it’s possible that the names might clash with some other gem.

The convention is to have a directory within lib/ with the same name as the gem. This way only sudoku.rb will be loaded from the load path and we can safely require 'sudoku/version' within sudoku.rb to access version.rb.

We’ll add version.rb in lib/sudoku and we should now have a gem directory structure that looks like this:

sudoku
├── lib
│   ├── sudoku
│   │   └── version.rb
│   └── sudoku.rb
└── sudoku.gemspec

Let’s now add the version information in version.rb:

module Sudoku.
  VERSION = '0.0.0'
end

And now use this in the gemspec by using Sudoku::VERSION instead of using the string “0.0.0” directly.

$LOAD_PATH.push File.expand_path("../lib", __FILE__)
require 'sudoku/version'

Gem::Specification.new do |s|
  s.name        = "sudoku"
  s.version     = Sudoku::VERSION
  # .. other stuff
end

The first line adds the lib/ directory of your gem to ruby’s load path, so you can include the files within that directory relative to your load path. For instance require 'sudoku' would load lib/sudoku.rb. Here we need the version.rb file for accessing Sudoku::VERSION constant, so we use require 'sudoku/version' to add lib/sudoku/version.rb.

As you may have noticed, we’re still not any closer to having a working sudoku solver, but we’ve learned a lot about how to create a bare gem and organize the files within it.

Don’t worry, we’ll eventually get to writing the actual sudoku solver. In the meanwhile, we’ll also look at publishing our awesome gem to rubygems.org and setting up tests using Test::Unit and Rspec in the next 2-3 posts.

[Subscribe to this blog to find out when the next part of this tutorial is published, or keep an eye on the first post in this series where I'll post the links to all published posts.]

Writing Ruby Gems – Part 1: Gem specifications

[This is the first part of a series of posts about writing a Ruby gem. The introductory post about this tutorial contains links to each part of the tutorial. Next post: Adding some code.]

The first thing to do when creating a new gem is to create a file called gemspec that contains information about the gem. The gemspec file will have the name of your gem, ie. my gemspec will be called yourgemname.gemspec.

(Once again, I’d recommend naming your gem something other than “sudoku” since that name is already taken and you’ll not be able to share your awesome gem on rubygems.org. For the rest of the post, I’ll use the name sudoku for the gem, and you will have to replace it as required.)

Create a directory for your sudoku solver gem and add a gemspec file. In your gemspec file, add the following code, replacing the values for name, authors, email and homepage:

Gem::Specification.new do |s|
 s.name        = "sudoku"
 s.version     = '0.0.0'
 s.authors     = ["Nithin Bekal"]
 s.email       = ["me@nithinbekal.com"]

 s.summary     = "Sudoku solver in Ruby"
 s.description = "Solves Sudoku puzzles. D'uh!"
 s.homepage    = "http://github.com/nithinbekal/sudoku"
end

Now that you’ve written the gemspec, build the gem using the “gem build” command:

$ gem build sudoku.gemspec
 Successfully built RubyGem
 Name: sudoku
 Version: 0.0.0
 File: sudoku-0.0.0.gem

This command will package your gem project into a gem file that can be used to install the gem. This file will have the structure gem_name-version.gem (with the gem name and version coming from the gemspec). Our sudoku gem is at version 0.0.0, so the gem file will have the name sudoku-0.0.0.gem. You can use this file to install the gem for your ruby installation with “gem install sudoku-0.0.0.gem”.

$ gem install sudoku-0.0.0.gem
Successfully installed sudoku-0.0.0
1 gem installed
Installing ri documentation for sudoku-0.0.0...
Installing RDoc documentation for sudoku-0.0.0...

You can check that the gem is available by doing:

$ gem list | grep sudoku
sudoku (0.0.0)

If you check the gem installation folder for the gem and you’ll see that there are no files in it. To find the location where the gem will be installed, do “gem env” on the terminal:

$ gem env
RubyGems Environment:
 - RUBYGEMS VERSION: 1.8.5
 - RUBY VERSION: 1.9.2 (2011-02-18 patchlevel 180) [i686-linux]
 - INSTALLATION DIRECTORY: /home/username/.rvm/gems/ruby-1.9.2-p180
 - RUBY EXECUTABLE: /home/username/.rvm/rubies/ruby-1.9.2-p180/bin/ruby
 - EXECUTABLE DIRECTORY: /home/username/.rvm/gems/ruby-1.9.2-p180/bin
 - RUBYGEMS PLATFORMS:
    - ruby
    - x86-linux
 - GEM PATHS:
    - /home/username/.rvm/gems/ruby-1.9.2-p180
    - /home/username/.rvm/gems/ruby-1.9.2-p180@global
 - GEM CONFIGURATION:
    - :update_sources => true
    - :verbose => true
    - :benchmark => false
    - :backtrace => false
    - :bulk_threshold => 1000
 - REMOTE SOURCES:
    - http://rubygems.org/

Go to the path shown as INSTALLATION DIRECTORY, and within that navigate to gems directory. Here, you will find your new sudoku gem in the directory sudoku-0.0.1. This directory will be empty now because we haven’t yet written any code for our awesome sudoku solver.

Now that we have created a gemspec, used it to build our (empty) gem and even installed it, you can sit back for a few minutes and bask in the glory of your awesome new gem. (Let’s ignore the fact for now that it does absolutely nothing. After all, eventually our gem will be able to solve any sudoku you throw at it.)

In the next post, we’ll look at the next few steps in writing our gem – adding a lib directory that contains all the logic and some source files for our gem.

[Subscribe to this blog to find out when the next part of this tutorial is published, or keep an eye on the first post in this series where I'll post the links to all published posts.]

Writing Ruby Gems

Creating a Ruby gem is a lot easier than it seems. Many tutorials about writing gems recommend using something like Jeweler or Hoe to create the structure of the gem for you.

Using such tools will make it much easier to get started with a gem, but building a gem from scratch will help you figure out how exactly those tools organize your gem’s structure. Here, we will walk through creating a gem from scratch, without generating any code.

The gem we are creating here is called sudoku, and it is supposed to be able to solve… er… sudoku puzzles. But this tutorial isn’t about creating a sudoku solver, so we’ll not worry too much about the logic that goes into a sudoku solver and instead focus on how we will package our gem.

The gem name sudoku is obviously taken (by me) and you can’t publish the gem to rubygems.org with the same name. (We will look at how to host the gems at rubygems.org in a future post.) I will be using the name sudoku for our gem in the rest of the tutorial, but you can use some other gem name (sudoku-yourname, perhaps?) and replace “sudoku” by your gem’s name wherever applicable.

The actual tutorial is split into several posts, each covering one small step in writing the gem. Here are the links:

1. Gem specifications
2. Adding some code
3. Publishing to rubygems.org
4. Setting up Test::Unit
5. Setting up Rspec

I’ll hopefully add more posts to this series in the coming days. These are some of the ideas for topics I’ll write about:

6. Adding an executable
7. C extensions in Gems
8. More on organizing the code
9. Gem version numbers

I’ve pushed the code for this project to github, so you can take a look at the latest code there.

[Subscribe to this blog to see when new posts are added to this series, or keep an eye on this page. You can also browse the Ruby related posts on this blog or browse my Delicious bookmarks related to rubygems.]

Tabs vs. spaces for indentation

A few days ago I was arguing with a friend about the right way to indent code. Being a spaces-for-indentation fanatic myself, I complained about the hard tabs he was using in one of his github repos and he in turn expressed shock that I actually waste time on this space-for-indentation thing.

If you’re an indentation fanatic, you would probably – like me – classify programmers into 4 categories:

  1. People indenting with spaces
  2. People indenting with tabs “\t”
  3. People who mix spaces and tabs
  4. People who don’t indent

Did I hear you mutter “That 4th type are NOT programmers”? Of course they aren’t. In fact, in my book they are right up there alongside Suaron‘s minions, Lord Voldemort‘s Death-Eaters, and Darth Vader and the Sith as the most evil creatures that ever walked on the earth.

Unfortunately for those of us that try to hold on to our sanity, there are hiring managers out there who hire these people and let them pollute others’ beautifully written code. As long as they are allowed to write code, we might as well accept the fact that they exist in the programming world.

Which brings me to the type 3 folks. Their mixture of tabs and spaces makes it a nightmare to read code, but at least you can convert the tabs in most editors and get something close to readable code. At least they try to indent, and that’s a lot better than code that’s fully left aligned. Anyway, if you’re one of the people doing this… stop it. Just stop. Please.

That finally leaves the two sets of programmers that indent exclusively using either spaces or tabs. Personally I prefer spaces, but that’s probably because I write Ruby code often and using two spaces for indentation is the common convention in the Ruby community.

Why use tabs?

Tabs for indentation has one clear advantage over spaces. You can customize how much indentation should appear. For instance, if your teammate likes 8 column indentation (what kind of people do you work with?) and you prefer 4 columns, well, you don’t have to do anything. Once you’ve set your editor to display 4 column tabs, you don’t have to worry about how many columns your teammates see. As long as you both consistently use hard tabs, you’ll both be fine.

Why use spaces?

Most Ruby and Python programmers would swear by spaces-for-indentation. People in both these communities almost unanimously agree with indenting with spaces and it’s especially important in Python because of its use of whitespace for delimiting blocks.

The best thing about this is that it makes the code look consistent everywhere. Since everybody in these communities uses the same indentation rules, it’s not much of a problem, but no such consensus in many other languages.

Conventions

While looking around for conventions in major open source projects on indentation, I came across the Linux coding style document:

Tabs are 8 characters, and thus indentations are also 8 characters. There are heretic movements that try to make indentations 4 (or even 2!) characters deep, and that is akin to trying to define the value of PI to be 3. Rationale: The whole idea behind indentation is to clearly define where a block of control starts and ends. Especially when you’ve been looking at your screen for 20 straight hours, you’ll find it a lot easier to see how the indentation works if you have large indentations.

I find this strange. Draconian almost. Eight character indentation seems so 1980. And yet one of the most important open source projects in the world imposes these rules, and some of the best programmers in the world follow them. In such cases, using tabs for indentation makes sense, because then heretics like me can set the tab width to 4 (or even 2! – what madness!) and happily read the code.

[To the author of the document quoted above: If you've been looking at your screen for 20 hours straight, that means you ought to be taking a break, rather than increasing indent levels on your program. ;-) ]

Anyway, what’s most important about indentation is that you -and your team – do it consistently and follow the same guidelines. Here’s what Jeff Atwood of Coding Horror has to say of tabs v/s spaces in Death to the Space Infidels!:

Choose tabs, choose spaces, choose whatever layout conventions make sense to you and your team. It doesn’t actually matter which coding styles you pick. What does matter is that you, and everyone else on your team, sticks with those conventions and uses them consistently.

Which he cheekily followed up with:

That said, only a moron would use tabs to format their code.

I certainly won’t disagree with that. The second part, especially.

Related articles: