• Aucun résultat trouvé

In this chapter we describe the Denali data abstraction mechanism, and show how user-dened abstractions can be implemented. As in non-logic programming languages that support user-dened data abstraction, this is done by rst xing a concrete representation for the abstract objects, and then realizing the interface in terms of this representation.

This approach diers, however, from other languages that have extended Prolog, none of which distinguish between the means used to represent objects and the means used to denote them as terms.

The problem of implementing data abstractions in Denali is complicated by their intricacy. We begin in Section 4.1 by developing the requirements for these abstractions.

In most languages, a data abstraction provides a set of abstract objects and operations.

Denali abstractions also provide a denotation scheme, a set of modes, and a unication predicate.

A data abstraction can be implemented in three ways. The rst way, which we mention for the sake of completeness, is by providing it as a built-in abstraction. This method is appropriate only for abstractions of broad applicability such as integers and lists. Fixing the set of built-in abstractions is a crucial part of a full language design.

However, as we are concerned only with designing the framework of Denali, we do not 67

68 4. Data abstraction in Denali address this aspect here.

The remaining two implementation techniques apply to user-dened abstractions, the focus of this chapter. We illustrate in Section 4.2 the technique of implicit implementa-tion, in which denotations double as the concrete representations of objects. Abstract modes are dened in terms of denotations. The unication procedure is not explicitly implemented; instead, a set of equations is given that species the desired procedure. The language implementation, in turn, synthesizes the appropriate unication procedure.

In Section 4.3 we explain the technique of explicit implementation. With this tech-nique, the programmer uses the objects of some other sort to stand as the concrete representation. Exploiting levels of abstraction in this way leads to more exibility in program design than does implicit implementation. However, the implementation pro-cess is more complicated. The denotation scheme, the abstract modes, the unication procedure, and any exported predicates all must be explicitly implemented in terms of the concrete representation.

In Section 4.4 we discuss the dierences between implicitand explicit implementation, and explain the circumstances under which each approach is applicable and appropriate.

We conclude our development of Denali in Section 4.5 by summarizing the role of abstraction in reasoning about Denali programs.

4.1 Requirements

In this section we develop requirements for data abstraction in Denali. Since a data abstraction encapsulates all of the information needed to characterize the objects of some sort, it must include the three forms of external information we assumed present when describing predicate abstraction in Chapter 2. This includes function signatures, mode denitions, and implementations of unication. A data abstraction also provides a set of predicates.

We begin in Section 4.1.1 by examining the role of data abstraction in conventional languages, and continue in Section 4.1.2 by considering the role of terms as abstract ob-jects in Prolog. In Section 4.1.3 we synthesize our observations into a set of requirements

4.1. Requirements 69 for the Denali data abstraction mechanism.

4.1.1 Data abstraction in conventional languages

Data abstractions appear in one form or another in almost all programming languages.

Built-in implementations of data abstractions that appear almost universally include scalar types such as integers and data structures such as arrays. Many modern languages also provide facilities that support the construction of user-dened data abstractions.

The role of a data abstraction is to provide a set of objects together with a set of operations to create, modify, and observe them. For example, languages that support integers generally provide constants, implementations of the standard arithmetic func-tions, and comparison relations. In some cases, an operation is logically related to a particular abstraction even though it is not presented as such. For example, array and record update operations are often described as special cases of assignment.

A trend in modern languages has been to support the construction of user-dened data abstractions that present the same kind of interfaces as their built-in counterparts.

The programmer can design extensions to the set of data types provided by a language, tailoring the language's expressive power to the requirements of the application.

Almost inseparable from the concept of data abstraction is the idea of encapsulation.

Ideally, the only way to manipulate the objects of an abstraction should be through the means provided by the abstraction's interface. If this principle is observed when implementing a data abstraction, several benets accrue. The meaning of the abstraction can be specied by describing the behavior of the components of its interface. Because of this, two implementations can be considered equivalent if they present behaviorally identical interfaces. Equivalent implementations can be freely interchanged without fear of altering the behavior of clients of the abstraction. When the principle of encapsulation is observed, the interface need not be bound to any particular means of representing abstract objects.

This last property is intrinsic to implementing built-in types, and is one of the con-tributions of early programming languages. Thus, the implementation of integers in almost all programming languages is hidden from the programmer. The principle of

en-70 4. Data abstraction in Denali capsulation has been extended to user-dened abstractions. For example, two properly constructed implementations of a set abstraction, one based upon arrays and the other upon binary trees, can be transparently interchanged.

4.1.2 Data abstraction in Prolog

The requirements for data abstraction in the context of a logic language are more exten-sive than for the conventional case considered above. The source of the dierence is the central role of unication and the need to denote directly the values of objects within the text of programs. Although Prolog provides no facilities for constructing user-dened data abstractions, it implicitly supplies a single built-in data type. We analyze below the role of this type in Prolog, in the process developing further insight into the requirements for Denali's data abstraction mechanism.

The only built-in type in pure Prolog is the uninterpreted term. Terms serve the same role in Prolog as objects do in imperative languages. They are similar, in some respects, to records. The most signicant dierence is that terms can contain, or can even be, variables. Anything from an individual variable to a ground term is an acceptable object in Prolog. This property is one source of Prolog's expressive power.

A data abstraction should provide all of the operations needed to manipulate its abstract objects. In pure Prolog, the only means of manipulating terms is by unifying and instantiating them. Because these two operations are central to the logic program-ming paradigm, and because there is only one built-in data type, it is convenient to regard them as built-in components of the Prolog interpreter. They could, however, be regarded as abstract operations supplied by the single built-in type. The importance of this distinction will become clear in Denali, in which more than one data abstraction can appear.

We have not been careful thus far to distinguish the terms provided by Prolog from the abstract objects they denote. It is important, however, to draw a distinction between an abstract object, its denotation, and its internal representation. It is dicult to motivate the dierence in pure Prolog since uninterpreted terms can conveniently serve as both denotation and representation. Instead, we examine standard Prolog [Clocksin 81] to

4.1. Requirements 71 illustrate our point.

A specialized inx list notation is used extensively in Prolog programs. In this nota-tion, a single list object can have two or more distinct denotations. In an implementation of Prolog, each list has a unique internal representation that is distinct from any deno-tation. List denotations must be translated into this representation before they can be manipulated with unication and instantiation.

The example above illustrates that a denotation is a syntactic artifact that need have no direct relationship to the representation of an object. This is especially true since denotations and representations are generally chosen to suit dierent criteria. The means used to denote the objects provided by a data abstraction should be part of the syntactic interface of the abstraction, and not a consequence of its implementation. Similar issues, as we have seen, arise in connection with conventional languages.

4.1.3 Denali interfaces

We have discussed the nature of data abstractions in both conventional and logic lan-guages. The underlying idea is that an abstraction must provide a set of abstract objects in a way that separates the means of manipulating the objects from the means of imple-menting them. The mechanisms provided by an abstraction for manipulating its objects depends in part upon the nature of the language and in part upon the nature of the abstraction.

The interface of an abstraction must provide the syntactic information that clients need to use the abstract objects. We now describe the style of interface presented by data abstractions in Denali. Although we will eventually need to explain how implementations associate meaning with interfaces, we will concentrate for now upon their form.

The list below summarizes the ve ways in which Denali objects can be derived and observed. It provides the starting point for the design of data abstraction in Denali:

72 4. Data abstraction in Denali nat =

cluster

denoted by

0: !nat s: nat!nat +: nat;nat!nat

modes

any>gnd