Tutorial: The "new" (&) Operator


 

Sometimes it is desirable to explicitly request that a new object is instantiated, instead of relying on the coercion mechanism to create objects tranparently whenever an object is required and the denoted entity is a pattern or a pattern reference.

One reason why the transparency might be unwanted is that the semantics may depend on having fresh objects. This is actually mostly a matter of convenience and performance, since it is typically because the implementation of a pattern depends on the initialization values for instances of basic patterns. E.g. a new integer has the value zero, and a new string is empty.

If some piece of syntax (<Merge>, actually), should denote a fresh, newly instantiated object, then just put the "new" operator in front of it:

"&" <Merge>

As usual, there is a "concurrent version" creating an object which is also a component:

"&" "|" <Merge>

If you are explicitly requesting a new object and the given syntax denotes an existing object, there is a compile-time (well, analysis time) error and the program is rejected.

Renewing an object reference

One extension in gbeta compared to traditional BETA is the possibility to use the "&" operator with a name which denotes an object reference (a "dynamic reference," declared with the "^" marker). This used to be a static semantic error.

The semantics in gbeta is that a new instance of the declared type is created, and the object reference is made to refer to that new object. This is similar to the creation syntax "!!" in Eiffel. It is nothing but syntactic sugar for an explicit object instantiation followed by a reference assignment, e.g.

(#
   ir: ^integer
do 
   (* This: *)
   &iref[];
   (* .. is the same as: *)
   &integer[]->iref[];

   (* And this: *)
   &iref;
   (* .. is the same as: *)
   &integer[]->iref[]; 
   iref;
#)

Whether or not the (newly created) object should be executed is determined by the "[]" marker: when this marker is present in an imperative (or in an evaluation), the denoted entity is identified ("a pointer to it is computed") but nothing more happens. When it is not present, the do-part is executed, as always. Since the execution of an integer is a no-op, nobody would notice in this particular example, though.

Caching

One special reason why it might be important to explicitly request a fresh object is that, traditionally, BETA allows a compiler to set up caching for all objects which are not explicitly requested to be new. This only applies to objects created as a result of coercion from pattern or pattern reference to object in an imperative. This is normally known by the term inserted item even though that is also the name of a syntactic category which does not cover all the cases where caching is allowed. As an example:

(#
   p: (# value: @integer do value+1->value exit value #)
do 
   (for 3 repeat p->putint for)
#)

This is should print "123" with caching, since the (same) imperative mentioning p will use the same instance of the pattern denoted by p which was created by coercion. In gbeta (and in the Mjolner BETA System) it prints "111". In contrast:

(#
   p: (# value: @integer do value+1->value exit value #)
do 
   (for 3 repeat &p->putint for)
#)

This must definitely print "111", even according to "the BETA book."

However, this has never been implemented for any cases where it could be detected (in terms of program state), and it is generally frowned upon, so it is not (and will not be) implemented to do caching of inserted items in gbeta. Think of it as a non-issue.

On the other hand, it might very well be interesting to provide this functionality explicitly, such that:

(#
   p: (# value: @integer do value+1->value exit value #)
do 
   (for 3 repeat @p->putint for)
#)

will print "123" thus making caching an explicit choice by the programmer. This has not been implemented, and the grammar does not even allow it.

The next topic is general block structure, which might seem somewhat alien to users of many other languages.

 


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