Compatibility With BETA? |
The language gbeta is closely related to the language BETA, but there are also some differences. Here is a comparison between BETA as it is implemented in the Mjolner BETA System and gbeta. The comparison focuses on the aspects of gbeta which are not backward compatible, so it is primarily useful if you already know BETA and want to know the few cases where your BETA experience is not directly applicable. Some differences arise from the fact that the implementation of gbeta is an early compiler/interpreter where language design issues and the generality of the implementation have been primary concerns, whereas the Mjolner BETA System represents a trade-off between performance and generality designed for real-world programming. A few other differences represent real language design issues. SimilaritiesBETA and gbeta are very similar in many ways; basically gbeta is a generalization of BETA, so a legal BETA program is also a legal gbeta program. Additionally, gbeta lifts a number of restrictions that are present in BETA, thereby allowing a large class of new programs. For example, BETA does not allow combination of patterns, only the special case which is single inheritance; BETA does not support inheriting from any other type of pattern than the compile time constant ones, i.e., one cannot use a virtual pattern or a pattern variable as a super-pattern; virtuals can not be further-bound to other virtuals in BETA, only to compile-time constant patterns; and virtuals can not have lower bounds in BETA. As a consequence, only gbeta supports propagating pattern combination, dynamic control structures, and a large number of other designs and constructs that rely on the greater generality of the basic elements such as patterns and objects. This means that you can use gbeta to write BETA programs, but it would be a good idea to consider all the new possibilities as well. Nevertheless, any experience with BETA and how to write good programs in that kind of language can be transferred directly to gbeta. DifferencesThere are some differences between BETA and gbeta, and they are severe enough to make it impossible to run existing BETA programs directly in almost all cases. The differences fall in two groups, namely the "real" language design issues and the implementation dependent issues. For performance reasons, the built-in patterns (like integer and char) are special in Mjolner BETA; for example, it is not possible to declare a dynamic reference to such an object, only a static reference (this means that noboby can obtain a pointer to such an object, so it does not have to be a full-fledged object). Moreover, these patterns cannot be used as super-patterns, and the ## marker cannot be used to obtain the patterns themselves. None of these restrictions apply in gbeta, all patterns and objects are full-fledged and support all usage modes. Another issue which is concerned with specific implementation properties of the Mjolner BETA System is that of external calls (calls to C libraries etc). Mjolner uses external function calls in the basic BETA libraries, in order to provide access to operating system facilities such as standard input and standard output. Since there is no general support (yet) for external function calls in gbeta, it is not possible to use the basic libraries from Mjolner BETA directly. Since all programs written for Mjolner BETA ultimately include these basic libraries, it is not possible to run any of these programs as gbeta programs directly. A modified version of the basic BETA libraries will hopefully be provided as part of the gbeta system at a later point, when the copyright issues have been sorted out. A few additional more subtle incompatibilities between BETA and gbeta are described in the thesis; see the papers page. As mentioned, there are also some genuine language design issues. These are cases where gbeta deliberately has been given a semantics which is different from the BETA semantics. Firstly, the repetition assignment semantics has been changed. Repetitions (similar to arrays or vectors in other languages) can be assigned, and the effect is that each element from the source is assigned to each element of the destination, one after the other. For example:
So far, there is no difference between the BETA semantics and the gbeta semantics. The difference appears when coercion markers (page 5 in the tutorial) are used, as in this example:
Another difference is that gbeta strictly enforces the distinction between patterns which have different origins, i.e., two patterns in gbeta are different patterns if they are nested in two different objects, even if they are associated with the exact same declarations in the source code (the language BETA requires this, but the Mjolner BETA System is implemented in such a way that it is not enforced). The distinction based on origins is required for type soundness. Moreover, it enables the type system to distinguish between an unbounded number of patterns in the type analysis, even though all programs have finite size. This enables the gbeta type analysis to help programmers discover inconsistencies at a level that most type systems cannot capture. To illustrate the value of fine grained type systems, consider this: In Pascal and many other languages it is possible to declare new types which are "just like integers, but still different" (e.g. type Age = Integer). They behave like integers and they have the same operations, but the type analyzer complains if somebody tries to mix them in the same expression. This is good for correctness because such "really just integer" types may be used to represent conceptually different things like the age and the height of people, and it just does not make sense to add an age and a height. Note that such types would be considered the same under a structural type equivalence, and in that case the type system would be of no help in catching errors that arise from confusing them. The point is that the fine grained type system allows us to distinguish between entities because we know that they are different, even if a formal semantic description of them would look the same. This has been taken one step further in BETA and gbeta with the strict origin policy. As an example, it is possible in gbeta to have a University pattern, and inside that a Student pattern, and the type analysis will ensure that references to students from two different universities are not type compatible. When this kind of very strict separation is desired, the type system is there to support it; when it is not desired, the solution is simply to take the Student pattern out of the University pattern and let them live beside each other instead of nesting one inside the other. Without block structure and without strict origin checking, the permissive/unsafe design is the only available choice. There are a few other cases where gbeta is not backward compatible with BETA, but they are more subtle and make no difference in most cases; they are described in detail in the PhD thesis. |