$7.5 A SIMPLE CLASS 175 Feature Feature classification, Computation Memory y implementation Routine Attribute No result Returns result Procedure Function Uniform access One aspect of the preceding classifications may at first appear disturbing and has perhaps caught your attention.In many cases,we should be able to manipulate objects,for example a point p/,without having to worry about whether the internal representation of p/is cartesian,polar or other.Is it appropriate,then,to distinguish explicitly between attributes and functions? The answer depends on whose view we consider:the supplier's view (as seen by the author of the class itself,here PO/NT)or the client's view (as seen by the author of a class that uses PO/ND).For the supplier,the distinction between attributes and functions is meaningful and necessary,since in some cases you will want to implement a feature by storage and in others by computation,and the decision must be reflected somewhere. What would be wrong,however,would be to force the clients to be aware of the difference.If I am accessing pl,I want to be able to find out its x or its p without having to know how such queries are implemented. See "Uniform The Uniform Access principle,introduced in the discussion of modularity,answers Access".page 55. this concern.The principle states that a client should be able to access a property of an object using a single notation,whether the property is implemented by memory or by computation(space or time,attribute or routine).We shall follow this important principle in devising a notation for feature call below:the expression denoting the value of the x feature for p/will always be plxx whether its effect is to access a field of an object or to execute a routine. As you will have noted,the uncertainty can only exist for queries without arguments, which may be implemented as functions or as attributes.A command must be a procedure; a query with arguments must be a function,since attributes cannot have arguments
§7.5 A SIMPLE CLASS 175 Uniform access One aspect of the preceding classifications may at first appear disturbing and has perhaps caught your attention. In many cases, we should be able to manipulate objects, for example a point p1, without having to worry about whether the internal representation of p1 is cartesian, polar or other. Is it appropriate, then, to distinguish explicitly between attributes and functions? The answer depends on whose view we consider: the supplier’s view (as seen by the author of the class itself, here POINT) or the client’s view (as seen by the author of a class that uses POINT). For the supplier, the distinction between attributes and functions is meaningful and necessary, since in some cases you will want to implement a feature by storage and in others by computation, and the decision must be reflected somewhere. What would be wrong, however, would be to force the clients to be aware of the difference. If I am accessing p1, I want to be able to find out its x or its ρ without having to know how such queries are implemented. The Uniform Access principle, introduced in the discussion of modularity, answers this concern. The principle states that a client should be able to access a property of an object using a single notation, whether the property is implemented by memory or by computation (space or time, attribute or routine). We shall follow this important principle in devising a notation for feature call below: the expression denoting the value of the x feature for p1 will always be p1 ● x whether its effect is to access a field of an object or to execute a routine. As you will have noted, the uncertainty can only exist for queries without arguments, which may be implemented as functions or as attributes. A command must be a procedure; a query with arguments must be a function, since attributes cannot have arguments. Procedure Routine Function Attribute No result Returns result Computation Memory Feature Feature classification, by implementation See “Uniform Access”, page 55
176 THE STATIC STRUCTURE:CLASSES $7.5 The Uniform Access principle is essential to guarantee the autonomy of the components of a system.It preserves the class designer's freedom to experiment with various implementation techniques without disturbing the clients. Pascal,C and Ada violate the principle by providing a different notation for a function call and for an attribute access.For such non-object-oriented languages this is understandable (although we have seen that Algol W,a 1966 predecessor to Pascal, satisfied uniform access).More recent languages such as C++and Java also do not enforce the principle.Departing from Uniform Access may cause any internal representation change (such as the switch from polar to cartesian or some other representation)to cause upheaval in many client classes.This is a primary source of instability in software development. The Uniform Access principle also yields a requirement on documentation “Using assertions techniques.If we are to apply the principle consistently,we must ensure that it is not fordocumentation: possible to determ ine,from the official documentation on a class,whether a query without the short form of a class”,page389. arguments is a function or an attribute.This will be one of the properties of the standard mechanism for documenting a class,known as the short form. The class Here is a version of the class text for PO/NT.(Any occurrence of consecutive dashes- introduces a comment,which extends to the end of the line;comments are explanations intended for the reader of the class text and do not affect the semantics of the class. indexing description:"Two-dimensional points" class POINT feature x,y:REAL --Abscissa and ordinate rho:REAL is --Distance to origin (0,0) do Result :sqrt(x ^2 +y^2) end theta:REAL is --Angle to horizontal axis do ...Left to reader (exercise E7.3,page 216) end
176 THE STATIC STRUCTURE: CLASSES §7.5 The Uniform Access principle is essential to guarantee the autonomy of the components of a system. It preserves the class designer’s freedom to experiment with various implementation techniques without disturbing the clients. Pascal, C and Ada violate the principle by providing a different notation for a function call and for an attribute access. For such non-object-oriented languages this is understandable (although we have seen that Algol W, a 1966 predecessor to Pascal, satisfied uniform access). More recent languages such as C++ and Java also do not enforce the principle. Departing from Uniform Access may cause any internal representation change (such as the switch from polar to cartesian or some other representation) to cause upheaval in many client classes. This is a primary source of instability in software development. The Uniform Access principle also yields a requirement on documentation techniques. If we are to apply the principle consistently, we must ensure that it is not possible to determine, from the official documentation on a class, whether a query without arguments is a function or an attribute. This will be one of the properties of the standard mechanism for documenting a class, known as the short form. The class Here is a version of the class text for POINT. (Any occurrence of consecutive dashes -- introduces a comment, which extends to the end of the line; comments are explanations intended for the reader of the class text and do not affect the semantics of the class.) indexing description: "Two-dimensional points" class POINT feature x, y: REAL -- Abscissa and ordinate rho: REAL is -- Distance to origin (0, 0) do Result := sqrt (x ^ 2 + y ^ 2) end theta: REAL is -- Angle to horizontal axis do …Left to reader (exercise E7.3, page 216) º end “Using assertions for documentation: the short form of a class”, page 389
$7.6 BASIC CONVENTIONS 177 distance (p:POINT):REAL is --Distance to p do Result :sqrt((x-px)2+(y-p.y)^2) end translate (a,b:REAL)is --Move by a horizontally,b vertically. do x=x+a y:=y+b end scale (factor:REAL)is --Scale by factor. do x=factor米x y=factor米y end rotate (p:POINT:angle:REAL)is --Rotate around p by angle. do ...Left to reader (exercise E7.3,page 216)... end end The next few sections explain in detail the non-obvious aspects of this class text. The class mainly consists of a clause listing the various features and introduced by the keyword feature.There is also an indexing clause giving general description information,useful to readers of the class but with no effect on its execution semantics. Later on we will learn three optional clauses:inherit for inheritance,creation for non- default creation and invariant for introducing class invariants;we will also see how to include two or more feature clauses in one class. Z.6 BASIC CONVENTIONS Class PO/N7 shows a number of techniques which will be used throughout later examples. Let us first look at the basic conventions. Recognizing feature kinds Features x and y are just declared as being oftype REAL,with no associated algorithm;so they can only be attributes.All other features have a clause of the form
§7.6 BASIC CONVENTIONS 177 distance (p: POINT): REAL is -- Distance to p do Result := sqrt ((x – p ● x) ^ 2 + (y – p ● y) ^ 2) end translate (a, b: REAL) is -- Move by a horizontally, b vertically. do x := x + a y := y + b end scale (factor: REAL) is -- Scale by factor. do x := factor ✳ x y := factor ✳ y end rotate (p: POINT; angle: REAL) is -- Rotate around p by angle. do …Left to reader (exercise E7.3, page 216) … end end The next few sections explain in detail the non-obvious aspects of this class text. The class mainly consists of a clause listing the various features and introduced by the keyword feature. There is also an indexing clause giving general description information, useful to readers of the class but with no effect on its execution semantics. Later on we will learn three optional clauses: inherit for inheritance, creation for nondefault creation and invariant for introducing class invariants; we will also see how to include two or more feature clauses in one class. 7.6 BASIC CONVENTIONS Class POINT shows a number of techniques which will be used throughout later examples. Let us first look at the basic conventions. Recognizing feature kinds Features x and y are just declared as being of type REAL, with no associated algorithm; so they can only be attributes. All other features have a clause of the form
178 THE STATIC STRUCTURE:CLASSES $7.6 do Instructions... end which defines an algorithm;this indicates the feature is a routine.Routines rho,theta and distance are declared as returning a result,of type REAL in all cases,as indicated by declarations of the form rho:REAL is .. This defines them as functions.The other two,translate and scale,do not return a result(since they do not have a result declaration of the form:T for some type T),and so they are procedures. Since x and y are attributes,while rho and theta are functions,the representation chosen in this particular class for points is cartesian. Routine bodies and header comments The body of a routine (the do clause)is a sequence of instructions.You can use Fordetails see "The semicolons,in the Algol-Pascal tradition,to separate successive instructions and War of the Semico- declarations,but the semicolons are optional.We will omit them for simplicity between lons",page 897. elements on separate lines,but will always include them to delimit instructions or declarations appearing on the same line. All the instructions in the routines of class PO/NT are assignments;for assignment, the notation uses the:symbol (again borrowed from the Algol-Pascal conventions).This symbol should of course not be confused with the equality symbol =used,as in mathematics,as a comparison operator. Another convention of the notation is the use of header comments.As already noted, comments are introduced by two consecutive dashes--.They may appear at any place in a class text where the class author feels that readers will benefit from an explanation.A special role is played by the header comment which,as a general style rule,should appear at the beginning ofevery routine,after the keyword is,indented as shown by the examples in class POINT.Such a header comment should tersely express the purpose of the routine. Attributes should also have a header comment immediately following their declaration,aligned with routine's header comments,as illustrated here with x and y. The indexing clause At the beginning of the class comes a clause starting with the keyword indexing.It See"A note about contains a single entry,labeled description.The indexing clause has no effect on software component index- execution,but serves to associate information with the class.In its general form it contains img'”,page78. zero or more entries of the form index word:index value,index value,... where the index word is an arbitrary identifier,and each index value is an arbitrary language element (identifier,integer,string...)
178 THE STATIC STRUCTURE: CLASSES §7.6 is do … Instructions… end which defines an algorithm; this indicates the feature is a routine. Routines rho, theta and distance are declared as returning a result, of type REAL in all cases, as indicated by declarations of the form rho: REAL is … This defines them as functions. The other two, translate and scale, do not return a result (since they do not have a result declaration of the form :T for some type T), and so they are procedures. Since x and y are attributes, while rho and theta are functions, the representation chosen in this particular class for points is cartesian. Routine bodies and header comments The body of a routine (the do clause) is a sequence of instructions. You can use semicolons, in the Algol-Pascal tradition, to separate successive instructions and declarations, but the semicolons are optional. We will omit them for simplicity between elements on separate lines, but will always include them to delimit instructions or declarations appearing on the same line. All the instructions in the routines of class POINT are assignments; for assignment, the notation uses the := symbol (again borrowed from the Algol-Pascal conventions). This symbol should of course not be confused with the equality symbol =, used, as in mathematics, as a comparison operator. Another convention of the notation is the use of header comments. As already noted, comments are introduced by two consecutive dashes --. They may appear at any place in a class text where the class author feels that readers will benefit from an explanation. A special role is played by the header comment which, as a general style rule, should appear at the beginning of every routine, after the keyword is, indented as shown by the examples in class POINT. Such a header comment should tersely express the purpose of the routine. Attributes should also have a header comment immediately following their declaration, aligned with routine’s header comments, as illustrated here with x and y. The indexing clause At the beginning of the class comes a clause starting with the keyword indexing. It contains a single entry, labeled description. The indexing clause has no effect on software execution, but serves to associate information with the class. In its general form it contains zero or more entries of the form index_word: index_value, index_value, … where the index_word is an arbitrary identifier, and each index_value is an arbitrary language element (identifier, integer, string…). For details see “The War of the Semicolons”, page 897. See “A note about component indexing”, page 78
$7.6 BASIC CONVENTIONS 179 The benefit is twofold: Readers of the class get a summary of its properties,without having to see the details. Chapter 36 In a software development environment supporting reuse,query tools (often known describes a general as browsers)can use the indexing information to help potential users find out about 0-0 browsing available classes;the tools can let the users enter various search words and match mechanism. them with the index words and values. The example has a single indexing entry,with description as index word and,as index value,a string describing the purpose of the class.All classes in this book,save for short examples,will include a description entry.You are strongly encouraged to follow this example and begin every class text with an indexing clause providing a concise overview of the class,in the same way that every routine begins with a header comment. “Self-Documenta- Both indexing clauses and header comments are faithful applications of the Self- tion",page 54. Documentation principle:as much as possible of a module's documentation should appear in the text of the module itself. Denoting a function's result We need another convention to understand the texts of the functions in class PO/NT:rho, theta and distance. An"entity”isa Any language that supports functions (value-returning routines)must offer a name denoting a notation allowing the body of a function to set the value which will be retumed by any value.Full defini- particular call.The convention used here is simple:it relies on a predefined entity name, tion on page 213. Result,denoting the value that the call will return.For example,the body of rho contains an assignment to Result: Result :sqrt (x^2 +y^2) Result is a reserved word,and may only appear in functions.In a function declared as having a result of type T,Result is treated in the same way as other entities,and may be assigned values through assignment instructions such as the above. Initialization rules Any call to the function will return,as its result,the final value assigned to Result will be given in"The during the call's execution.That value always exists since language rules (to be seen in creation instruc- detail later)require every execution of the routine,when it starts,to initialize Result to a tion",page 232. preset value.For a REAL the initialization value is zero;so a function of the form non_negative value (x:REAL):REAL is --The value ofx if positive;zero otherwise. do if x>0.0 then Result:=x end end will always return a well-defined value(as described by the header comment)even though the conditional instruction has no else part
§7.6 BASIC CONVENTIONS 179 The benefit is twofold: • Readers of the class get a summary of its properties, without having to see the details. • In a software development environment supporting reuse, query tools (often known as browsers) can use the indexing information to help potential users find out about available classes; the tools can let the users enter various search words and match them with the index words and values. The example has a single indexing entry, with description as index word and, as index value, a string describing the purpose of the class. All classes in this book, save for short examples, will include a description entry. You are strongly encouraged to follow this example and begin every class text with an indexing clause providing a concise overview of the class, in the same way that every routine begins with a header comment. Both indexing clauses and header comments are faithful applications of the SelfDocumentation principle: as much as possible of a module’s documentation should appear in the text of the module itself. Denoting a function’s result We need another convention to understand the texts of the functions in class POINT: rho, theta and distance. Any language that supports functions (value-returning routines) must offer a notation allowing the body of a function to set the value which will be returned by any particular call. The convention used here is simple: it relies on a predefined entity name, Result, denoting the value that the call will return. For example, the body of rho contains an assignment to Result: Result := sqrt (x ^ 2 + y ^ 2) Result is a reserved word, and may only appear in functions. In a function declared as having a result of type T, Result is treated in the same way as other entities, and may be assigned values through assignment instructions such as the above. Any call to the function will return, as its result, the final value assigned to Result during the call’s execution. That value always exists since language rules (to be seen in detail later) require every execution of the routine, when it starts, to initialize Result to a preset value. For a REAL the initialization value is zero; so a function of the form non_negative_value (x: REAL): REAL is -- The value of x if positive; zero otherwise. do if x > 0.0 then Result := x end end will always return a well-defined value (as described by the header comment) even though the conditional instruction has no else part. Chapter 36 describes a general O-O browsing mechanism. “Self-Documentation”, page 54. An “entity” is a name denoting a value. Full definition on page 213. Initialization rules will be given in “The creation instruction”, page 232