Do you know any programming language features that help to detect bugs early in the software development process – ideally at compile-time or else as early as possible at run-time?
Examples of well-known and effective bug-reducing features are:
- Static typing and generic types: type incompatibility errors are detected by the compiler
- Design by Contract (TM), also called Contract Programming: invalid values are quickly detected at runtime (through preconditions, postconditions and class invariants)
- Unit testing
I ask this question in the context of improving an object-oriented programming language (called Obix) which has been designed from the ground up to ‘make it easy to quickly write reliable code’. Besides the features mentioned above this language also incorporates other Fail-fast features such as:
- Objects are immutable by default
- Void (null) values are not allowed by default
The aim is to add more Fail-fast concepts to the language. If you know other features which help to write less error-prone code then please let us know. Thank you.
3
Go has a few:
-
Any unused imports are errors (not sure if this is bug catching, certainly good code style)
-
No implicit conversions,
var i int = .5
is an error, not a warning or an automatic truncation. -
Keying off of 2, being strongly statically typed serves to catch many errors.
-
Everything is 0 initialized (sensibly so) so there are no null pointers.
-
Some sort of unit test support built in. I haven’t dug too deeply into this.
Another one that pops into my head is Haskell
-
Strongly statically typed. Ask any Haskeller about the type system, it catches 99% of my haskell errors before I even get to running it.
-
Design by contract to an extent
Int->Int->Int
though this would be encapsulated in most function declarations in languages -
Purely Functional. If a function works once in a scenario, it’ll always work.
However in general, good practices in a language with poor safety beat a careless programmer in a safe language. Take for example C (Not a jab at C, but it leans more on the user to double check that things are sane) clearly it is possible to write good robust code in C despite it’s lack of features for this. In the end the programmer>programming language.
1
Start by taking a long, hard look at the original Ada programming language, from 1983. Ada was designed specifically for writing highly reliable systems that would have very long life cycles.
Strong static typing. Strong semantics. Easily readable. Tasking built-in.
You can hack ’til you crack, but you have to WORK at it, and the resulting code LOOKS like it. This is a feature: it warns the next poor maintenance schlub that Here Be Dragons.
There’s a remark from the dawn of computing: Running with subscript checking enabled during checkout, and turning it off for production, is like wearing your lifejacket in the harbor and then taking it off when you go out onto the open ocean. Note that Ada required that subscript checking be turned ON by default, and required programmers to turn it off explicitly if they were so bold.
Some test I would like to have (probably not all of them all the time):
- Boundary testing: Many errors occur on the bounds of the domain (like putting
<
in stead of<=
). So if you could somehow support this, it would be grate. (Let the programmer defineint[0-90]
and so no value above 90 or below 0 will be allowed). - Robustness testing: Is almost the same as the above, but aims to test values that should not be supported, and see that the app doesn’t crash.
- The above may be combined to one test -> the software doesn’t crash, and just testing random values from the whole domain (random integers, random strings)
- Domain knowledge: A convenient way to insert tests by domain experts will be good. That means someone that has very good knowledge in banking but no clue in programming should be able to write some tests, according to his knowledge.
- Program graph: Build a program graph, including branches and loops. And while running a set of tests, mark the lines of code tested, and those that where never touched. So the programmertester can know what part of the code was never tested. (May be time and space consuming)
- Asserts: Give the programmer an option to make an assert while testing, that will be taken out by the compiler in production. This is a very old idea no one really implemented in a nice way (if at all).
1