The cost of catching a bug at compile time



I'm know there are a lot of developers out there who live in the C# world or the Java world and solely in that world. They think scripting languages, which previously meant interpreted languages but now just seems to mean "without strong typing" aren't as good as C# and Java.

When you look at benchmarks of programming languages on execution speed, there is a strong case for C# and Java.. but in a way, since you're using an interpreted language in the first place.. does speed matter so much? In the age of load balanced web servers, DHTs and other distributed solutions.. don't these technologies help wear down the idea of that a little bit of speed in a straight line is so important? I feel I could use Facebook and Google who turn to C++ and scripting languages and cut out C# and Java in middle as an example for my arguments but it doesn't seem the right way to sell my thoughts.

If we say, forget about that tiny speed difference, and hell, let me throw the memory footprint argument out the window too since you aren't managing it and you don't free it as soon as possible... is there still a bit of your "professional opinion" that says C# and Java are somehow more appropriate for most of your professional development work than Perl or Python? And if so why? I ask because I used to feel the same way. That there was something slightly less "professional" about weakly typed languages. When I finished my Software Engineering degree I felt like I had the mindset of an engineer, using delicately crafted tools to deliver inch perfect precision. In the end I think I narrowed it down to one idea: A phrase I heard a lot at University coming from lecturers and also in some widely respected 2000-era programming books too. The advice goes like this:

"It's better to catch a bug at compile time rather than runtime"


Damn, that's some good advice. Undeniably true. I wouldn't knock it for the world. Yet, I want to propose the opposite. Rather, I'd like to merely suggest the opposite and see if I can't make you a little bit more open to those type-less scripting languages. I'll obviously start by poking strongly-typed languages. I'll say "hey, it's great you have strongly typed arguments. You can only invoke this function with an integer or else you get a compile error:



string GetWeekDay(int day_of_week);

//invoke like this
String day = GetWeekDay(5);


Awesome! However, ummm, not all integers are valid inputs are they? Only 1-7 are (or 0-6). Damn. You see you've left yourself a hole there. Strong typing only goes half way. It only validates the type, it doesn't validate the actual data in the true sense of testing that it is within the bounds of the domain. It's a half solution. We could talk about enumerations here but I'd probably find an example like PrintLotteryNumbers() where enumerating numbers just seems wrong.

Now, Object Oriented programming is some gnarly shit, if you'll indulge me in using that ridiculous phrase. You can make types. Yep, you certainly can! See what you do is create an object of type DayOfWeek, who gets the "full validation" at instantiation and then for the rest of the journey and your other calls to GetWeekDay() ... you know you're as sound as a pound.

It could look something like this:



class DayOfWeek {
public DayOfWeek(int day_of_week) {
...
}
}

string GetWeekDay(DayOfWeek day_of_week);

//invoke like this
x = GetWeekDay(new DayOfWeek(5));



But lets get real for a second. How do you instantiate a type? You still got the same problem, only you moved the problem somewhere else. Since the language only understands the basic types: int, string, char, double etc and the fact you don't have static assert.. and the fact that you still have to validate stuff coming in, especially when it comes in from the environment like the console or a GUI.. what is strong typing really giving you? Better documentation and slightly faster execution time? Autocomplete in the 500MB footprint of the Eclipse IDE? I'm under the impression C# does have something synonymous to static assert but it goes out of the window when the input is input isn't hard-coded. Put very simply, at this point, my argument here is that strong typing and data validation are not the same thing.

Removing Bugs



So lets me elaborate on where my mind went next:

"It's better to catch a bug at compile time rather than runtime... because the sooner you find a bug the sooner you fix it"


You write Java programs with strong typing and there are still bugs at runtime. Testing, as I hope you'll agree, is the most effective way to get rid of bugs. This article completely hinges on accepting that fact and I won't deny it. This is just gibberish bullshit if you won't accept my premise here. Testing is how you ensure programs work correctly. Unit and Automated testing gives something even cooler. You can quickly test the entire system and be sure your system works.

"because the sooner you find a bug the sooner you fix it"


That's right. The sooner you get code into your Unit testing system, Automated Testing system or into the hands of your human testing systems the sooner you can know it's right. Perl and Python are optimised for getting things done quickly. Shit, in Perl you can do these things:



my $output = "my value is $value\n"; # string interpolation

if $variable =~ "/{0-23}:{0-59}/"; # use Regular Expressions inline

my $system_details = `uname -a`; # run a shell command inline.

my @aces = grep { $_->{"suit"} eq 'ACE' } @cards;# lambdas.

$hash->{"pretend"}->{"this"}->{"exists"}; # auto-vivification

my ($filename, $access_mode, $lock) = @array; # array expansion

my @array[1..1000,34,@replace]; # slicing and dicing of an array



All of that weird crazy-to-the-un-informed syntactic shit gives you short cuts and reliable flexibility to beat Java and C# in one area. Finding bugs quickly! Getting code out the door quickly by getting straight into the Unit Testing stuff. The real testing stuff. It's quick, short, concise and I've worked at Agile companies where the Perl team can turn on a six-pence. If Agile is about delivering quickly, Perl and Python are the languages to go with it. Even if you hate those features above (and some are questionable) the language is still built around that idea and it still rings true whilst writing it.

I'd like to just end this post here to be honest. I've summed up my general feelings about which languages allow you to get to real testing first and why it's a great thing. However I don't want to start a wankfest over whose application has the fewest characters. That isn't the metric I'm going for here. I don't want to play Perl-Golf. To me it's about which languages express business logic tightly. Which languages don't need huge reams of framework code. There are other ideas inside Perl and Python than merely syntax that help you build things quickly. I don't want people to say to me "I could wrap that in a one-line Java function" because of course you still have to write and maintain that original function in the first place.

Python delivers minimal lines of code. You can see more on-screen. It isn't just about that however. If you're a Perl dev, you can solve complex problems with out a strong typing OO overhead. You can import additional features like OO when you want them. Even then you can do it in a flexible way. If you want strong typing we give you real strong typing.. where the parameters to your functions do get full validation

Perl doesn't care about encapsulation. You can use Monkey-patching (aka Duck-punching) so your testing classes can be really fucking invasive and yet it doesn't actually require any meta-language built on the language to describe the dependency injection. Business logic is simple and clean. Testing is Testing. We don't need contracts to make the two co-operate. (I'm looking at you C#!). Finally, Perl devs go on about this stupid thing called CPAN. Something to do with.. instantly having a database of code on hand. I'm not a tried and true Perl developer so I feel some indescribable dislike of it.. but it does fit in nicely with my argument. Perl is: A language that allows you to write code quickly, easily, comfortably and it allows you to get it tested early so you know it's robust, solid, trustworthy code. The very thing that engineers are supposed to aim for. The extra time you free up, in my opinion, easily offsets the few times a bug is caused by interpreting a number as a string.

Perl is far from perfect but it is built with some good goals in mind and it does offer an effective programming style.

If I could subtly convince you that more time writing unit tests is equal to or greater than the benefit of strong typing, I've done my job. Perl and Python developers aren't amateurs. They merely don't see the point of strong typing because they live in a world where it doesn't exist and it doesn't matter. They wonder why you do.

Perhaps you should give the languages a try some time...