Why has Obix been created?
This question can best be explained by first stating the following two undisputable facts subsisting in the world of software development:
It is very hard to create error-free software; in most cases this is even impossible.
The costs generated through errors in software often increase dramatically when the errors are detected late in the process of developing-testing-using the software application.
Although every programmer probably agrees that too many errors remain in the large majority of software delivered to customers, and that it takes a lot of time, discipline and experience to find and repair those errors, most people are surprised when they hear the 'real numbers' provided by several prominent studies that have been done to prove and quantify the above facts. The highly praised book Code complete, second edition, 2004 (ISBN 0-7356-1967-0), written by Steve McConnell contains the following interesting conclusions, which are the results of studies done by IBM, NASA, etc.
concerning the number of errors:
[Industry average experience is about 1 - 25 errors per 1000 lines of code for delivered software] (middle of page 521)
This means that:
A mid-size application consisting of 50000 instructions still contains not less than 50 to 1250 errors when the software is delivered to the customer(s)!
If a big application (+- 1 million instructions) contains 1000 errors it is still considered to be of 'high reliability', because there is only 1 error in 1000 lines of code.
concerning the costs generated by these errors:
[Researchers at HP, IBM, Hughes Aircraft, TRW, and other organizations have found that purging an error by the beginning of construction allows rework to be done 10 to 100 times less expensively than when it's done in the last part of the process, during system test or after release] (top of page 29)
[... software defect removal is actually the most expensive and time-consuming form of work for software] (study at IBM, bottom of page 474)
A famous example of the dramatic consequences of a bug is the Ariane 5 launcher that crashed on June 4, 1996. The crash was due to an arithmetic overflow error at runtime, when a 64 bit floating-point number was converted to a 16 bit signed integer. The (uninsured!) cost was estimated to be 500.000.000 USD!
A more frequent example would be an error detected in an ERP application after the software has been delivered to hundreds or thousands of customers. Although it might only take a few minutes for the programmer to fix the bug in the source code, the total costs can easily be orders of magnitude higher, because of the need for redeployment and retesting, the need for informing and updating all customers, perhaps the need for correcting wrong results stored in databases, and so on; not to mention the customer's loss of time, frustration and decrease of trust in the software and the software company.
The lesson is clear and leads to the following important 'Fail fast!' principle:
To increase the reliability and maintainability, and reduce costs, software errors must be detected and repaired as early as possible. Errors should preferably be automatically detected at compile-time, or else as early as possible at run-time.
Experience shows that applying the 'Fail fast!' principle considerably reduces the long-term total costs of software developments.
Although no programming language can of course prevent programmers from writing bad or erroneous programs, the goal pursuit with Obix is to provide a language with facilities that protect against errors which are hard to find and repair. Thus Obix helps programmers to write more reliable and maintainable code in less time.
This goal is achieved through a unique combination of proven and innovative concepts which all support the 'Fail fast!' rule. Moreover, error-prone programming techniques, such as automatic type conversions, are prevented whenever possible.
Experience shows that the benefits of bug-reducing features grow quickly with
If this support is not embedded in the language, then much more time, discipline and experience is required from the programmers. This can easily distract from the main task of solving a business problem.
From the outset Obix has been designed with these concepts kept in mind, in order to immediately integrate them in the language. This approach allows a better implementation than in the case of merely adding these features later to a language, or offering them as an optional, maybe third-party, extension. First, the language doesn't suffer from restrictions or exceptional cases which are sometimes inevitable or necessary because of the need for backward compatibility. Secondly, they seamlessly evolve with new versions of the language, because they are part of the language. Thirdly, they are easier to understand and use and no special syntax constructs have to be invented. Finally, the application doesn't depend on optional extensions to the language. As a result, programmers are much more motivated (or compelled) to use them, which leads to better and easier to maintain software.
Obix incorporates the concepts briefly enumerated in the table below. Designed to work together, they lead to more reliability, robustness and maintainability. Please refer to the links if you want to get more information right now.
Table 1. Concepts built into Obix
| Concept | Rationale | Link |
|---|---|---|
| Compiled language | a maximum of coding errors should be detected at compile-time | |
| Unit testing | one of the most effective means to detect errors | Chapter 21, Testing |
| Contract programming (Design by Contract) | very powerful means to protect software elements against invalid uses | Chapter 17, Contract programming |
| Static typing | more type safety; more errors detected at compile-time; better design of types enforced | Chapter 16, Static typing |
| The concept of types, factories and services | enforces implementation hiding and simplifies the design of software components | |
| Handling of void values | setting attributes and input/output arguments invalidly to void is quickly detected at compile- or runtime | Chapter 12, Void values |
| Feature redefinition in child types | leads to a more expressive and safer typing system | Chapter 18, Feature redefinition |
| Generic types | more type safety and no error-prone casts at run-time | Chapter 19, Generic types |
| Favor for immutable objects | simplifies objects and makes them thread-safe and less error-prone | Chapter 14, Object immutability |
| Everything is an object | eliminates different behavior between primitive types, arrays and 'real' objects | |
| Arithmetic overflow errors caught immediately | eliminates evil consequences of arithmetic overflows | |
| Enumerated types | type-safe enumerateds; more errors detected at compile-time | Chapter 11, Enumerated type |
| the 'case enumerated of' instruction | detect 'I forgot that enumerated value' errors at compile-time | (not yet available) |
| the 'case type of' instruction | detect 'I forgot that child-type' errors at compile-time | the section called “case type of instruction” |
| Multiple type inheritance | a proven and required concept of Object Oriented (OO) programming languages | Chapter 15, Type inheritance |
| Runtime error handling | needs high consideration and should be supported by the language | Chapter 13, Runtime error handling |
| Default values for attributes and input arguments | simplifies object creation and command execution | |
| Multiple output arguments | enables error-code error handling | the section called “Resource error” |
| Source code templates | avoid code duplication | Chapter 20, Source code templates |
Most importantly, it is the unique combination and the interaction of the above mentioned concepts that help to write better software. In this context, it is again interesting to quote the book Code complete:
[... if project developers are striving for a higher defect-detection rate, they need to use a combination of techniques] (last paragraph on page 470)
It goes without saying that more productivity is another important goal pursuit in software development projects.
Obviously, the above mentioned concepts for increased reliability and maintainability also increase productivity, because less bugs leads to less time spent to find and repair bugs.
Another important feature of Obix is the ability to embed Java source code directly in Obix source code. This means that the huge amount of existing Java software can immediately be used by any application developed with Obix. The inverse is true too. Obix code can be called from within Java code, and data can easily be exchanged between Obix and Java. (For more information, please refer to Chapter 10, Embedded Java source code)
At the time of writing, a framework for quickly developing Graphical User Interface (GUI) applications is under construction. The basic idea is to provide a generic HTML user interface for all types of objects, without the need to write a single line of GUI code. This is especially useful for quickly developing prototypes, or for delivering a preliminary version to testers and end-users. If needed, the user interface can programmatically be customized. In any case, the GUI code is completely separated from other code.
Besides increased reliability and productivity, Obix should also be easy to learn and use.
The syntax of source code has not been designed to be the most writeable possible (i.e. less keystrokes), but the most readable possible, so that less experienced programmers don't struggle with cryptic and ambiguous syntax constructs. Furthermore, everyone should be able to quickly understand code written by somebody else.
Another aim was to automatically enforce some important Object Oriented (OO) concepts through the language itself, so that the programmer doesn't need to first learn and then apply good programming practices related to those concepts. For example, the hiding of implementation details is automatically enforced through Obix's concept of types (i.e. the interface) and factories (i.e. the implementation) (see the section called “Type” and the section called “Factory”).
Obix's favor for strict default values helps programmers to write better code without extra efforts. For example, objects are immutable by default, void values are not allowed by default, and code is statically typed by default. As said already, Obix also supports the programmer by preventing error-prone programming techniques.
The programmer is also released from the recurring and boring task of writing getters and setters and she or he doesn't have to deal with different and sometimes surprising or restrictive behaviors of primitive data types and arrays co-existing with 'real' objects, because in Obix everything is an object.
To summarize:
The aim of Obix is to provide an easy-to-learn-and-use programming language that helps to increase reliability, maintainability and productivity.