Active libraries are libraries which interact dynamically with the compiler to provide better services: meaningful error messages, library-specific optimizations, new language semantics, and so on. Traditional libraries are chunks of code that get grafted on your program in a very passive manner. Active libraries take an active role in the transformation of application concepts into code.
A good example of (future) active library is the tasking library in XL. This library will provide tasking support on a par with what Ada offers using built-in language constructs.
Code Generation Changes
In order to do that, the tasking library may need to modify the code generation, for instance creating exclusive regions for code segments that would not behave correctly if executed simultaneously by more than one task. The library implementors might also offer guarantees with respect to initialization and cleanup order.
This kind of changes will occur transparently to the programmer, having no observable effect in the absence of tasks (except possibly causing the code to be slightly less efficient.)
Semantics Changes
The library may also alter the semantics of existing constructs when used in conjunction with tasks. For example, it may supply an {entry} pragma to turn procedures into rendezvous entries -- special forms of procedure that can be called across task boundaries. Or it may add a {thread_local} pragma to declare thread-local storage.
Instead of silently modifying the code, the library in that case has observable effects on the meaning of existing entities such as variables or procedures. In other words, the library alters the default semantics.
New Semantics
Finally, the library may go one step further and add new semantics of its own. For instance, it may add a parallel statement which causes the execution of children statement in parallel:
parallel
RunTask1
RunTask2
RunTask3
IO.WriteLn "All 3 tasks completed"
The library in that scenario adds completely new semantics, with possibly arbitrary rules. To enforce these rules, it can emit meaningful error messages, for instance to forbid using a goto statement to jump out of a parallel statement.
More Choice
In the more traditional models, only the compiler vendor can offer such features. However, using the Mozart framework, a library can add these features by extending the compiler. As a result, Mozart should ultimately provide an increasing number of specialized capabilities for software developers.
In addition to choice, Mozart offers flexibility. The initial Ada-83 tasking model had to be revised because it was too restricted. But changing it proved difficult, because tasking was built into the Ada language itself. There is no such problem with Mozart. Just as multiple libraries can coexist, multiple active libraries can coexist peacefully and offer complementary features. For instance, different libraries could offer real-time tasking or distributed tasking.
|