• Ingen resultater fundet

8.2 Convenience Constructs

8.2.5 Improved Transparency

Greatly inspired by David Ungar, a mechanism has been added togbetawhich improves on the transparency of computed vs. stored values. This mechanism does not introduce new syntax. It is very simple, and it is backward compatible with Beta, because it gives meaning to constructs that would otherwise have caused static semantic errors. The error that used to be reported was that there was an attempt to look up an attribute in a pattern (the Mjolner compiler would say `An object is expected here').

The new meaning is obtained by evaluating the pattern; if that delivers the identity of an object, then that object is used. For example:

(# door: (# open: (# ::: #)#);

house1: @(# frontDoor: @door #);

house2: @ (# frontDoor:

(# theDoor: ^door

do (* let me see, I think it is this one *)

::: ->theDoor[]

exit theDoor[]

#)

#) do

house1.frontDoor.open;

house2.frontDoor.open

#) Ex.

8-15

The point is that thefrontDoorattribute inhouse1is stored and thefrontDoor attribute in house2is computed, i.e., the former is an object and the latter produces an object when needed. Without this mechanism, it would have been necessary to change the usage of thefrontDoorof house2(by adding parenthe-ses to make it(house2.frontDoor).open); with this mechanism the two usage points can be identical. As always, the fact that the usages are independent of the chosen implementation of a given attribute improves on the possibilities for program reorganization and maintenance.

This transparency mechanism is specically oriented towards attributes that are used to access other attributes. If an attribute is itself the last element in the chain (e.g., a stand-alone name, or the last name in aRemoteconstruct), then the coercion which is available also without this mechanism already provides good support for changing the kind of an attribute without aecting usage points. Of course, it is still possible to become dependent on whetherfrontDoor is a pattern or an object by means of explicit coercion markers; for example

house1.frontDoor## is less-equal than door##, but house2.frontDoor##is not. This underscores the fact thatBetaandgbetahave very good transparency support as long as attributes are used without explicit coercion markers, but the transparency gets more and more compromised the more coercion markers there are, so they should preferably be kept in rather private areas of the source code, such as with parameters that are only used locally within a method.

Improving the Static Analysis

This chapter describes some mechanisms ingbetawhich enable a more exible and detailed management of the information which is used in the static analysis, thus allowing for a statically safe expression of some designs which could not be expressed safely if these mechanisms were removed from the language. Since we highly value the safety guarantees provided by static analysis, these mechanisms are important additions togbeta.

However, they have been designed with the rather idiosyncratic and formal-istic requirements of the static analysis in mind, so they do not support the comprehensibility of the source code very well. The decisions about where and how to use them will usually be concerned with technicalities rather than un-derstanding the overall conceptual universe of the program. It would probably be a good habit to maintain awareness about what aspects of a program express the essential design and what aspects are there to help the static analysis. In return, the static analysis might actually help improving the understanding of the program because false impressions of regularities may be unveiled when the static analysis is unable to verify them.

Section 9.1 describes the when imperative which supports a dynamic case selection based on patterns (type casing). Section 9.2 presents a mechanism which allows the specication of a lower bound on a virtual, thereby making certain usages of that pattern in contravariant positions safe. The next section, 9.3, describes virtual objects which allow for a more statically restricted way to provide arguments than the normal approach based on evaluations and enter -lists, and Sect. 9.4 describes the concept of disownment of a virtual, which makes it possible to further-bind a given virtual in certain ways, because certain other kinds of further-binding have been declared to be illegal.

Finally, Sect. 9.5 deals with a more profound change in the development of gbeta fromBeta: There are two kinds of object-like entities in Beta, namely items and components. The dierence is concerned with sequential vs. alter-nating or concurrent execution. These two kinds of entities have been unied into the single concept of objects in gbeta, and the support for non-sequential execution has been transferred to the domain of patterns by introducing a new,

173

basic pattern. One of the main benets obtained by this change is a clearer and more manageable static analysis treatment of non-sequential entities, and that is the reason why it is located in this chapter. Section 8.1.2 would actually t very well into this chapter, but we decided to put it in Sect. 8.1 because it is not just an improvement for static analysis but also an incompatible change in relation toBeta.

9.1 Type Casingthe

when

Imperative

A type case is a control structure which allows the selection of one of a given set

of bodies according to the actual (run-time) descriptive value associated with a given run-time entity, for example the class of an object.

Many people in the object-orientation community consider type casing an inherently inappropriate activity, as explained in Sect. 9.1.1. However, we be-lieve that some mechanism for dynamic rediscovery of the applicability of static information is needed, as argued in Sect. 9.1.2not just because real projects are imperfect, but because there is a genuine trade-o between the overall com-plexity of a system and the completeness of statically checkable information about run-time entities such as objects. Next, Sect. 9.1.3, describes howBeta can already do type casing, why that is not completely safe, how thewhen im-perative in gbeta solves the safety problem, and how it works in more detail.

Finally, Sect. 9.1.4 explains why the whenimperative is a more powerful con-struct than traditional type casing based on purely static denotations of the descriptive entities.