Tutorial: Primitive Entities


 

An important idea behind BETA was to create such a general, orthogonal, and minimal language that it would be easy to get to know well, and still it would be so expressive that anything could be written in it in an elegant and maintainable form.

Because of this, there should not be many predefined languge entities. However, a few are needed, and they are presented here.

Basic patterns

All patterns are either constructed from other patterns (using specialization and main parts) or predefined. The set of predefined patterns may be viewed as a parameter, defining a family of BETA languages which differ only in the choice of predefined patterns. Because of this, it has not been given that much attention what selection of basic patterns are present in gbeta, it simply supports the same basic patterns as the Mjolner BETA System as well as a few extras. It would be nice to have different widths of integers, unicode characters, and infinite precision arithmetic types as well, but that remains a future project. In Mjolner BETA System, by the way, some changes are being introduced in this area right now.

The basic patterns for simple values are boolean, char, integer, real, and string. The string basic pattern is new compared to Mjolner BETA System, and it will be described below. The others are well-known. Each integer object, e.g., is a container for one value from the set of integer values supported (again a language family parameter). In evaluations, an integer object will deliver one integer value ("its value"), and when assigned to it will accept one integer value. Similarly with the others. All these basic patterns have a primitive value attribute. It is not an object, and you cannot obtain a reference to it or ask for its type or inherit from it. It is used for access to the value of primitive objects in specializations, e.g.:

(#
   talking_integer: @integer
     (# do 'Hi, mom, I''m '->stdio; 
        value->putint; 
        ' now!\n'->stdio
     #)
do 
   5->talking_integer
#)

These input/output properties are the atomic (irreducible) elements in the recursive definition of input/output properties: Any object will deliver a (possibly composite) value when evaluated, and this value is computed by looking up exit-lists recursively until a primitive pattern or an object reference or a pattern reference ("[]", "##"), or a literal expression (like "3.1415926" or "'Ho! Ho! Ho!'"), or a primitive value (like the index variable of a for-imperative) is encountered.

A string contains a string of characters as a value, i.e. it is immutable. This provides a nice compromise between sharing references to (heavy) "text" objects and copying these objects all the time. The problem is that copying a text object everytime it is used as an argument is too expensive, and sharing it by tranferring an object reference gives rise to aliasing. This is bad aliasing, because it is not motivated by the modeling relation (there is no analogous sharing in the conceptual model of the application domain), but exclusively motivated by performance considerations. It is possible that the problem lies in the fact that the standard text pattern in the Mjolner BETA System basic libraries uses repetitions in the enter- and exit-lists, and repetitions of instances of basic patterns are a too low-level construct in the Mjolner BETA System to support read-only access (which is normally achieved using a pattern that has only an exit-part and which exits whatever we want to have read-only access to).

Anyway, thestring basic pattern provides a solution because it allows sharing at the implementation level (value assignment of a string can be just an assignment of a pointer) and semantically works like other values: If you have a "7" in an integer variable, nobody will ever be able to change "7" into anything else, and hence the variable will not change because of "internal aliasing" (somebody else referring to the contents). As a result, a string is both fast and safe. On the other hand, it cannot be "edited", so if you want to change the individual characters a lot, copy the string into an oldfashioned repetition of char, and change the contents as you like, then possibly copy it back into a string.

There are three primitive operations on strings: aString.length delivers the length of the string, aString.at accepts an integer value and delivers the character at that position. In the future, there will possibly be some substring support, but string generally should remain a simple thing. Finally, string has a value attribute like the other basic (value) patterns. As an example:

(# 
   s: @string
do
   'test'->s;
   s.length->putint;
   2->s.at->stdio
#)

Concurrency

As mentioned in the co-routine and concurrency sections, concurrency has been re-defined from being a basic property (distinguishing "objects" and "components") into being a matter of types. An object has its own stack of execution iff it is a specialization of component, which is one more basic pattern. Along with component goes semaphore, since concurrency control is needed as soon as there is concurrency.

The primitive commands available with component have been mentioned in the concurrency section, and the primitive commands of semaphore are

P, V, and count

e.g. aSem.P, aSem.V, and aSem.count. These command are standard semaphore commands as defined by Dijkstra. The P command and the V command are executed by the run-time system in such a way the the number of V commands on any given semaphore is at all times greater than or equal to the number of P commands. This means that a thread can be delayed when it attempts to execute a P command, and it will not continue the execution before "somebody else" executes the V command on the same semaphore. This concurrency control primitive is sufficient to create higher level concurrency control abstractions, such as monitors and ports. Lots of details about this can be read in "the Beta book." Finally aSem.count evaluates to the number of threads waiting to execute because of the P/V command count constraint.

This concludes the gbeta tutorial.

 


Signed by: eernst@cs.auc.dk. Last Modified: 3-Jul-01