Trustworthy Languages

I was emailing with a VS languages team member yesterday, and asked him why he wrote a piece of code a certain way (just some sample snippet that he used to illustrate an idea in the email thread). He responded that he normally codes day-to-day in C++, and generally distrusts the language, so he tries to be as explicit as possible.

And that got me thinking about the concept of trustworthy languages.

It seems like sometimes we're so focused on the addition features related to many other engineering aspects and goals, that we normally don't ask the question: "at the end of the day, do you trust this language?" Before we can really answer that, it's important to understand why wouldn't you trust a language. I think some factors are:

  1. The interpreter/compiler generates logic that is counter-intuitive. This is often the case when the language tries to do the thinking for you, and allows you to skip being explicit by providing some default behavior if you don't supply specifics. The problem occurs when the compiler (by default) does something you don't expect, therefore causing unforseen runtime behavior or errors.
  2. The language implicitly resolves/casts/converts types, even when it's not "safe". For example, what will the code actually excute given   var X = "100" + 4? Will the results be "1004" or 104 or NAN? This of course, is an easy example, but in more complex logic, the type resolutions can really bite you in unexpected ways. This is also a problem with languages that play fast and loose with pointers. In this category, I'd place most scripting languages like Javascript, as well as VB with Option Strict OFF, and also C. In this respect, languages like Java, C#, and VB with Option Strict ON do pretty well.
  3. The language supports inheritance and OOP, but the rules of member resolution aren't clear. For example, let's say that you have a base class that defines a member, and you redefine it three subclasses later. Will the new member shadow the base class member, or replace it? "Good" languages force you to specify, but "bad" languages just allow you to define members however you want, and the compiler or runtime will decide what to do later. Or even better, what happens if you have multiple inheritance and inherit 2 base classes, each of which contain a member with the same name and arguments? Similarly speaking, what if you can, on top of all this other stuff, create AOP-style mix-in kinds of members? If a mix-in member clashes with a base-class member, who wins?
  4. The code just crashes... a lot... for no apparent reason (*cough*ActionScript*cough*)

This doesn't mean that languages can't have default unspecified behavior, but does mean that languages should be consistent and intuitive when doing default, unspecified things. And if people can't agree on the correct behavior, then it's not intuitive, therefore, untrustworthy. The more consistent and intuitive the results, the more the programmer will trust the compiler with decision making.