Its not an academic question. Names matter. What we call something says a lot about what we think it is, how it works, and how it is different from other things. A “horseless carriage” lives up to its name if it only does the same things as a horse-drawn carriage, but without the horse; if we call the same thing an “automobile,” we invite discussion of greater capabilities.
Id argue that most programming is “imperative”: we say, “Do this!” and the machine either does it or dies trying. Id also argue that this is the opposite of “non-procedural” programming, even though many people use “procedural” as the opposite of “object-oriented.” Object-oriented languages couple procedures closely to the data that they manipulate, but their logic is still imperative in tone; by contrast, a non-procedural system (such as Prolog or Aion—the latter now sold by Computer Associates as CleverPath Aion Business Rules Expert) states what is true and describes what is wanted and entrusts procedures under the hood—proven code, we hope—to do the work.
Assertive programming is somewhere in between. When a programming language enables assertions, were neither giving orders to the machine nor leaving the whole task in the hands of someone elses code. Were saying, “If were right so far, then this condition will hold.” Were inviting an auditor, as it were, to check our work and to warn us if we may have made a mistake.
This is where the differences arise. In Java 1.4, we make an assertion that results in a runtime check—and that throws an error, not just an exception, if the check fails. Unlike an exception, for which there may well be a workaround (hence the use of a “catch” clause), a violated assertion means that we dont really understand whats happening.
Java puts a high priority on being safe, rather than being efficiently risky by leaving out runtime checks: The decision on whether to enable or disable runtime assertion checking is therefore made at run time, optionally on a package-by-package basis to reflect varying tradeoffs between performance and level of trust, with the additional option of a cautious developer writing code that checks to see if assertions are enabled (and perhaps complaining if they are not).
In Visual Basic .Net, or in .Net managed code in general, theres a distinction between Debug.Assert (an assertion thats omitted from Release code) and Trace.Assert (which is checked at run time). With Debug assertions, its necessary to make sure that the assertion has no side effects: that it doesnt increment or decrement a counter, for example, which would mean that runtime behavior would differ from what a developer saw during debugging. Its also up to the developer to decide if the DEBUG symbol is defined in the release configuration: If its not, no one in the field can restore the safety mechanism.
Adding assertions in Java 1.4 fulfills a goal that language designer James Gosling had reluctantly deferred from early versions. Having assertions available in .Net programming, whether in Visual Basic or in C#, encourages developers to think more about their code instead of just banging on it until it (apparently) works. Like all safety mechanisms, though, assertions have to be used if they are to add value.
And thats where we come back to the meaning of the word, “assert.” The Oxford English Dictionary has the most colorful definition: the act of placing ones hand on the head of a slave, either to free him or to claim him for a task. Assertions in programming can have the same dual nature: we can put them to work until the job of development is done, and they can be freed when the code is ready to be deployed.