Which Language Combination?

I'm trying to be a better programmer. I have been writing and learning as much code as I can, the benefits are a threefold positive feedback loop:

  • Learning is, in itself, very pleasurable (it makes you feel clever, which is nice)
  • New knowledge transfers to, and enhances, existing skills
  • New tools and skills provide a greater resource for providing solutions

But, how does a developer know which skills to learn and which languages are best to learn with? (Assuming that you're learning for fun rather than as a work requirement.)

If Google is a good bench mark (assuming that they can take their pick of the best developers), one requirement (taken from an ad for a Software Engineer) asks for:

Fluency in two or more of C, C++, Java, Shell, PHP, Perl or Python.

If you are specifically aiming for a career at Google then making sure you are fluent in two major languages is probably the way to go, and there is certainly no downside to a developer broadening their skill set. In my experience, each foray into new languages has improved my PHP, and in turn, I feel pretty comfortable in Ruby and Python.

When deciding to learn something new: you could argue that PHP, Ruby, Python, Perl etc... are pretty much different brands of the same tool (procedural, interpreted languages). It's great to have the option to use each, but these languages are not necessarily complimentary. It is unlikely that you would write a system with a combination of PHP, Python and Ruby. But, it is conceivable that you could have a project requiring C, PHP and Erlang skills.

Rather than learning interchangable skills, complementary languages might offer the opportunity to become a more rounded developer:

  • Interpreted, procedural (PHP, Ruby, Python, JS)
  • Compiled, procedural (C/C++, Java)
  • Functional, concurrent (Erlang, Scala, F#)

Assuming that side stepping between similar languages is easier than picking up a completely new concept: it would seem learning these varied skills opens up more possibilities.

Sometimes I worry that by learning a particular, none mainstream, language (like Erlang) I could be backing the "wrong horse". However, bearing in mind my earlier ramblings, there's little downside to picking up a new way of doing things, for example Elang may not prove popular, but the functional approach will give me a head start learning F# or Scala.

This slide from Painless Payment Processing by Erik Stenman points out other benefits of learning more "unusual" languages:

Nice paradox:

The lack of Erlang programmers makes it easier for us to find great programmers.

  • There are many great C and Java programmers, I'm sure, but they are hidden by hordes of mediocre programmers.
  • Programmers who know a functional programming language are often passionate about programming.
  • Passionate programmers makes Great Programmers

Or am I talking nonsense?

Erlang FizzBuzz Showdown (Pt 1)

As I've become a little more familiar with Erlang I decided to leave the set text and test myself with a basic (often seen) programming challenge (FizzBuzz) and compare the solution with the languages I'm more familiar with.

FizzBuzz is a pretty simple set of rules (also known as Bizz Buzz) and is used for children's maths, drinking games and as a rather basic test given to programmers during job interviews (although it is so well known that it probably lost its value for this purpose a while back).

The rules (for programmers) are simple:

  • Print a list of numbers 1 - 100
  • If the number is exactly divisible by 3 print "Fizz"
  • If the number is exactly divisible by 5 print "Buzz"
  • If the number is exactly divisible by both 3 and 5 print "FizzBuzz"
  • Otherwise just print the number

Solving the problem breaks down to:

  • Create a range of numbers 1-100
  • Loop through each number and check it against the conditions
  • Print out the result
  • Repeat until 100

So far so simple, it is a pretty straight forward task that can be solved in a broad variety of ways.

Here's how I could achieve this in Python:

for i in range(1,101):
  
  if i % 3 == 0 and i % 5 == 0:
    print 'Fizzbuzz'
        
  elif i % 3 == 0:
    print 'Fizz'
        
  elif i % 5 == 0:
    print 'Buzz'
        
  else:
    print i

And PHP:

foreach (range(1,100) as $i)
{
    if (($i % 5 == 0) && ($i % 3 == 0))
    {
        echo "FizzBuzz\n";
    }
    elseif ($i % 3 == 0)
    {
        echo "Fizz\n";
    }
    elseif ($i % 5 == 0)
    {
        echo "Buzz\n";
    }
    else
    {
        echo "$i\n";
    }
}

Of course there are many variations depending on how short and/or "readable" you'd like it to be.

So, when it came to tackling this problem with Erlang I was a little surprised that I couldn't just launch into it. Approaching this problem functionally is a different kettle of fish. While there are built in functions that can help I chose to ignore them in favour of gaining a little more understanding.

In other languages creating a range of numbers was pretty straight forward and barley registered as a task, in Erlang I needed to think a little harder. There is no for or while loop easily to hand, the solution was a tail-recursive function. It might seem bloated to add this function, but if you compare the same function in Ruby, the Erlang function appears better suited to the task (also using tail recursion in none functional languages causes performance/stack issues so this is more for illustration):

% ERLANG

range(To,To,List) -> List ++ [To];
range(From,To,List) when From  range(From + 1, To, List ++ [From]).
#RUBY

def jRange(from,to,list)
  if from == to
    return list 

Erlang functions can have multiple entry points, so in this case the range function has two entry points:
  • One that accepts two identical values, a list and returns a list with the value added.
  • Another that accepts two different values, a list and adds the first value to the list, then calls the same function (itself) adding one to the first value.

As it matches the incoming conditions there is no need for if or else.

The problem with this loop is that it will go on infinitely if From is greater than To, to cover this we need a guard. This is a simple check that From is less than To:

range(To,To,List) -> [To|List];
range(From,To,List) when From  range(From, To -1, [To|List]).

And now we have an operational "range" function similar to those seen in Python, Ruby and PHP - however, Elang FizzBuzz can use it in various different ways. Another small change was to alter the way the list builds up, using List ++ [From] isn't very efficient and [To|List] does the job more elegantly.

In the next post I'll conclude building a FizzBuzz program (mistakes, solutions and better-practice included), check back tomorrow or subscribe to keep up to date.

Part 2 >>