mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-07 23:32:42 +01:00
Author:halw
Date:2008-10-22T21:23:04.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@94 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -32,7 +32,7 @@ For the classes using it, <code>console</code>, although a function, looks very
|
|||||||
|
|
||||||
The "Hello World" system at the beginning of this discussion (section [[4 Hello World|4]] ) used an output instruction of the form <code>io</code>. <code>put_string ( Some string )</code>. This is another example of the general scheme illustrated by <code>console</code>. Feature <code>io</code>, declared in <code>ANY</code> and hence usable by all classes, is a once function that returns an object of type <code>STANDARD_FILES</code> (another Kernel Library class) providing access to basic input and output features, one of which is procedure <code>put_string</code>. Because basic input and output must all work on the same files, <code>io</code> should clearly be a <code>once</code> function, shared by all classes that need these mechanisms.
|
The "Hello World" system at the beginning of this discussion (section [[4 Hello World|4]] ) used an output instruction of the form <code>io</code>. <code>put_string ( Some string )</code>. This is another example of the general scheme illustrated by <code>console</code>. Feature <code>io</code>, declared in <code>ANY</code> and hence usable by all classes, is a once function that returns an object of type <code>STANDARD_FILES</code> (another Kernel Library class) providing access to basic input and output features, one of which is procedure <code>put_string</code>. Because basic input and output must all work on the same files, <code>io</code> should clearly be a <code>once</code> function, shared by all classes that need these mechanisms.
|
||||||
|
|
||||||
==Constant and unique attributes==
|
==Constant attributes==
|
||||||
|
|
||||||
The attributes studied earlier were variable: each represents a field present in each instance of the class and changeable by its routines.
|
The attributes studied earlier were variable: each represents a field present in each instance of the class and changeable by its routines.
|
||||||
|
|
||||||
@@ -45,15 +45,6 @@ These will have the same value for every instance and hence do not need to occup
|
|||||||
|
|
||||||
What comes after the <code>=</code> is a manifest constant: a self-denoting value of the appropriate type. Manifest constants are available for integers, reals (also used for doubles), booleans ( <code>True</code> and <code>False</code>), characters (in single quotes, as <code>'A'</code>, with special characters expressed using a percent sign as in <code>'%N'</code> for new line, <code>'%B'</code> for backspace and <code>'%U'</code> for null).
|
What comes after the <code>=</code> is a manifest constant: a self-denoting value of the appropriate type. Manifest constants are available for integers, reals (also used for doubles), booleans ( <code>True</code> and <code>False</code>), characters (in single quotes, as <code>'A'</code>, with special characters expressed using a percent sign as in <code>'%N'</code> for new line, <code>'%B'</code> for backspace and <code>'%U'</code> for null).
|
||||||
|
|
||||||
For integer constants, it is also possible to avoid specifying the values. A declaration of the form
|
|
||||||
<code>
|
|
||||||
a, b, c, ... n : INTEGER = unique
|
|
||||||
</code>
|
|
||||||
|
|
||||||
introduces <code>a</code>, <code>b</code>, <code>c</code>, ... <code>n</code> as constant integer attributes, whose value are assigned by the Eiffel compiler rather than explicitly by the programmer. The values are different for all <code>unique</code> attributes in a system; they are all positive, and, in a single declaration such as the above, guaranteed to be consecutive (so that you may use an invariant property of the form <code>code > a and code < n</code> to express that <code>code</code> should be one of the values). This mechanism replaces the "enumerated types" found in many languages, without suffering from the same problems. (Enumerated types have an ill-defined place in the type system; and it is not clear what operations are permitted.)
|
|
||||||
|
|
||||||
You may use Unique values in conjunction with the <code>inspect</code> multi-branch instruction studied in the next section. They are only appropriate for codes that can take on a fixed number of well-defined values -- not as a way to program operations with many variants, a need better addressed by the object-oriented technique studied earlier and relying on inheritance, polymorphism, redeclaration and dynamic binding.
|
|
||||||
|
|
||||||
Manifest constants are also available for strings, using double quotes as in
|
Manifest constants are also available for strings, using double quotes as in
|
||||||
<code>
|
<code>
|
||||||
User_friendly_error_message: STRING is "Go get a life !"
|
User_friendly_error_message: STRING is "Go get a life !"
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ Once the client has attached <code>acc</code> to an object, it may call on this
|
|||||||
if acc.may_withdraw (3000) then
|
if acc.may_withdraw (3000) then
|
||||||
acc.withdraw (3000)
|
acc.withdraw (3000)
|
||||||
print (acc.balance)
|
print (acc.balance)
|
||||||
end</code>
|
end
|
||||||
|
</code>
|
||||||
|
|
||||||
These feature calls use dot notation, of the form <code>target_name.feature_name</code>, possibly followed by a list of arguments in parentheses. Features are of two kinds:
|
These feature calls use dot notation, of the form <code>target_name.feature_name</code>, possibly followed by a list of arguments in parentheses. Features are of two kinds:
|
||||||
* '''Routines''', such as <code>open</code>, <code>deposit</code>, <code>may_withdraw</code>, <code>withdraw</code>, represent computations applicable to instances of the class.
|
* '''Routines''', such as <code>open</code>, <code>deposit</code>, <code>may_withdraw</code>, <code>withdraw</code>, represent computations applicable to instances of the class.
|
||||||
@@ -44,9 +45,10 @@ Routines are further divided into '''procedures''' (commands, which do not retur
|
|||||||
|
|
||||||
In class <code>ACCOUNT</code>, is feature <code>balance</code> an attribute, or is it a function with no argument? The above extract of the client class <code>X</code> doesn't say, and this ambiguity is intentional. A client of <code>ACCOUNT</code> must not need to know how class <code>ACCOUNT</code> delivers an account's balance when requested: by looking up a field present in each account object, or by calling a function that computes the balance from other fields. Choosing between these techniques is the business of class <code>ACCOUNT</code>, not anybody else's. Because such implementation choices are often changed over the lifetime of a project, it is essential to protect clients against their effects. This is known as the '''Uniform Access Principle''', stating that the choice between representing a property through memory (an attribute) or through an algorithm (function) shall not affect how clients use it.
|
In class <code>ACCOUNT</code>, is feature <code>balance</code> an attribute, or is it a function with no argument? The above extract of the client class <code>X</code> doesn't say, and this ambiguity is intentional. A client of <code>ACCOUNT</code> must not need to know how class <code>ACCOUNT</code> delivers an account's balance when requested: by looking up a field present in each account object, or by calling a function that computes the balance from other fields. Choosing between these techniques is the business of class <code>ACCOUNT</code>, not anybody else's. Because such implementation choices are often changed over the lifetime of a project, it is essential to protect clients against their effects. This is known as the '''Uniform Access Principle''', stating that the choice between representing a property through memory (an attribute) or through an algorithm (function) shall not affect how clients use it.
|
||||||
|
|
||||||
So much for how client classes will typically use <code>ACCOUNT. </code> Below is a first sketch of how class <code>ACCOUNT</code> itself might look. Line segments beginning with <code>--</code> are comments. The class includes two <code>feature</code> clauses, introducing its features. The first begins with just the keyword <code>feature</code>, without further qualification; this means that the features declared in this clause are available (or "exported") to all clients of the class. The second clause is introduced by <code>feature</code> { <code>NONE</code>} to indicate that the feature that follows, called <code>add</code>, is available to no client. What appears between the braces is a list of client classes to which the corresponding features are available; <code>NONE</code> is a special class of the Kernel Library, which has no instances, so that <code>add</code> is in effect a secret feature, available only locally to the other routines of class <code>ACCOUNT</code>. So in a client class such as <code>X</code>, the call <code>acc.add ( -3000 )</code> would be invalid.
|
So much for how client classes will typically use <code>ACCOUNT. </code> Below is a first sketch of how class <code>ACCOUNT</code> itself might look. Line segments beginning with <code>--</code> are comments. The class includes two <code>feature</code> clauses, introducing its features. The first begins with just the keyword <code>feature</code>, without further qualification; this means that the features declared in this clause are available (or "exported") to all clients of the class. The second clause is introduced by <code>feature {NONE}</code> to indicate that the feature that follows, called <code>add</code>, is available to no client. What appears between the braces is a list of client classes to which the corresponding features are available; <code>NONE</code> is a special class of the Kernel Library, which has no instances, so that <code>add</code> is in effect a secret feature, available only locally to the other routines of class <code>ACCOUNT</code>. So in a client class such as <code>X</code>, the call <code>acc.add ( -3000 )</code> would be invalid.
|
||||||
<code>
|
<code>
|
||||||
class ACCOUNT
|
class
|
||||||
|
ACCOUNT
|
||||||
|
|
||||||
feature
|
feature
|
||||||
|
|
||||||
@@ -93,7 +95,7 @@ Let us examine the features in sequence. The <code>do</code> <code>...</code> <c
|
|||||||
|
|
||||||
The language definition guarantees automatic initialization, so that the initial balance of an account object will be zero after a creation instruction. Each type has a default initial value: zero for <code>INTEGER</code> and <code>REAL</code>, false for <code>BOOLEAN</code>, null character for <code>CHARACTER</code>, and a void reference for reference types. The class designer may also provide clients with different initialization options, as will be seen below in a revised version of this example.
|
The language definition guarantees automatic initialization, so that the initial balance of an account object will be zero after a creation instruction. Each type has a default initial value: zero for <code>INTEGER</code> and <code>REAL</code>, false for <code>BOOLEAN</code>, null character for <code>CHARACTER</code>, and a void reference for reference types. The class designer may also provide clients with different initialization options, as will be seen below in a revised version of this example.
|
||||||
|
|
||||||
The other public features, <code>withdraw deposit, open,</code> and <code>may_withdraw</code> are straight-forward routines. The special entity <code>Result</code>, used in <code>may_withdraw</code>, denotes the function result; it is initialized on function entry to the default value of the function's result type. You may only use <code>Result</code> in functions.
|
The other public features, <code>withdraw, deposit, open,</code> and <code>may_withdraw</code> are straight-forward routines. The special entity <code>Result</code>, used in <code>may_withdraw</code>, denotes the function result; it is initialized on function entry to the default value of the function's result type. You may only use <code>Result</code> in functions.
|
||||||
|
|
||||||
The secret procedure <code>add</code> serves for the implementation of the public procedures <code>deposit</code> and <code>withdraw</code>; the designer of <code>ACCOUNT</code> judged it too general to be exported by itself. The clause "<code>= 1000</code>" introduces <code>minimum_balance</code> as a constant attribute, which will not occupy any space in instances of the class; in contrast, every instance has a field for every non-constant attribute such as <code>balance</code>.
|
The secret procedure <code>add</code> serves for the implementation of the public procedures <code>deposit</code> and <code>withdraw</code>; the designer of <code>ACCOUNT</code> judged it too general to be exported by itself. The clause "<code>= 1000</code>" introduces <code>minimum_balance</code> as a constant attribute, which will not occupy any space in instances of the class; in contrast, every instance has a field for every non-constant attribute such as <code>balance</code>.
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ Eiffel encourages software developers to express formal properties of classes by
|
|||||||
|
|
||||||
With appropriate assertions, the class <code>ACCOUNT</code> becomes:
|
With appropriate assertions, the class <code>ACCOUNT</code> becomes:
|
||||||
<code>
|
<code>
|
||||||
class ACCOUNT
|
class
|
||||||
|
ACCOUNT
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ A typical use of agents with EiffelVision 2 is
|
|||||||
|
|
||||||
which says: "add <code>your_routine</code> to the list of operations to be performed whenever a <code>select</code> event (left click) happens on <code>ok_button</code>". <code>ok_button.select_actions</code> is the list of agents associated with the button and the event; in list classes, procedure <code>extend</code> adds an item at the end of a list. Here, the object to be added is the agent.
|
which says: "add <code>your_routine</code> to the list of operations to be performed whenever a <code>select</code> event (left click) happens on <code>ok_button</code>". <code>ok_button.select_actions</code> is the list of agents associated with the button and the event; in list classes, procedure <code>extend</code> adds an item at the end of a list. Here, the object to be added is the agent.
|
||||||
|
|
||||||
This enables the EiffelVision event-handling mechanism to find the appropriate agent when it processes an event, and call<code> call </code> on that agent to trigger the appropriate routine. EiffelVision doesn't know that it's <code> your_routine </code>; in fact, it doesn't know anything about your application. It simply finds an agent in the list, and calls<code> call</code> on it. For your part, as the author of a graphical application, you don't need to know how EiffelVision handles events; you simply associate the desired agents with the desired controls and events, and let EiffelVision 2 do the rest.
|
This enables the EiffelVision 2 event-handling mechanism to find the appropriate agent when it processes an event, and call <code>call</code> on that agent to trigger the appropriate routine. EiffelVision 2 doesn't know that it's <code>your_routine</code>; in fact, it doesn't know anything about your application. It simply finds an agent in the list, and calls <code>call</code> on it. For your part, as the author of a graphical application, you don't need to know how EiffelVision 2 handles events; you simply associate the desired agents with the desired controls and events, and let EiffelVision 2 do the rest.
|
||||||
|
|
||||||
Agents extend to many areas beyond GUIs. In '''numerical computation''', you may use an agent to pass to an "integrator" object a numerical function to be integrated over a certain interval. In yet another area, you can use agents (as in the iteration library of EiffelBase) to program '''iterators''' : mechanisms that repetitively apply an arbitrary operation -- represented by an agent -- to every element of a list, tree or other object structure. More generally, agent embody properties of the associated routines, opening the way to mechanism for '''reflection''', also called "introspection": the ability, during software execution, to discover properties of the software itself.
|
Agents extend to many areas beyond GUIs. In '''numerical computation''', you may use an agent to pass to an "integrator" object a numerical function to be integrated over a certain interval. In yet another area, you can use agents (as in the iteration library of EiffelBase) to program '''iterators''' : mechanisms that repetitively apply an arbitrary operation -- represented by an agent -- to every element of a list, tree or other object structure. More generally, agent embody properties of the associated routines, opening the way to mechanism for '''reflection''', also called "introspection": the ability, during software execution, to discover properties of the software itself.
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ The principle is that '''a routine must either succeed or fail''': it either ful
|
|||||||
|
|
||||||
Usually, only a few routines of a system will explicitly include a <code>rescue </code>clause. A routine that doesn't have an explicit <code>rescue</code> is considered to have an implicit one, which calls a routine <code>default_rescue</code> that by default does nothing, so that an exception will cause the routine to fail immediately, propagating the exception to the caller.
|
Usually, only a few routines of a system will explicitly include a <code>rescue </code>clause. A routine that doesn't have an explicit <code>rescue</code> is considered to have an implicit one, which calls a routine <code>default_rescue</code> that by default does nothing, so that an exception will cause the routine to fail immediately, propagating the exception to the caller.
|
||||||
|
|
||||||
An example using the exception mechanism is a routine <code> attempt_transmission </code> that tries to transmit a message over a phone line. The actual transmission is performed by an external, low-level routine <code> transmit </code>; once started, however, <code> transmit </code> may abruptly fail, triggering an exception, if the line is disconnected. Routine <code> attempt_transmission </code> tries the transmission at most 50 times; before returning to its caller, it sets a boolean attribute <code> successful </code> to <code> True </code> <code> or </code> <code> False </code> depending on the outcome. Here is the text of the routine:
|
An example using the exception mechanism is a routine <code>attempt_transmission</code> that tries to transmit a message over a phone line. The actual transmission is performed by an external, low-level routine <code>transmit</code>; once started, however, <code>transmit</code> may abruptly fail, triggering an exception, if the line is disconnected. Routine <code>attempt_transmission</code> tries the transmission at most 50 times; before returning to its caller, it sets a boolean attribute <code>successful</code> to <code>True</code> or <code>False</code> depending on the outcome. Here is the text of the routine:
|
||||||
<code>
|
<code>
|
||||||
attempt_transmission (message: STRING)
|
attempt_transmission (message: STRING)
|
||||||
-- Try to transmit message, at most 50 times.
|
-- Try to transmit message, at most 50 times.
|
||||||
|
|||||||
@@ -5,14 +5,16 @@
|
|||||||
Building software components (classes) as implementations of abstract data types yields systems with a solid architecture but does not in itself ensure reusability and extendibility. Two key techniques address the problem: generosity (unconstrained or constrained) and inheritance. Let us look first at the unconstrained form.
|
Building software components (classes) as implementations of abstract data types yields systems with a solid architecture but does not in itself ensure reusability and extendibility. Two key techniques address the problem: generosity (unconstrained or constrained) and inheritance. Let us look first at the unconstrained form.
|
||||||
|
|
||||||
To make a class generic is to give it '''formal generic parameters''' representing as unknown types, as in these examples from EiffelBase, an open-source library covering basic data structures and algorithms:
|
To make a class generic is to give it '''formal generic parameters''' representing as unknown types, as in these examples from EiffelBase, an open-source library covering basic data structures and algorithms:
|
||||||
<code>ARRAY [G]
|
<code>
|
||||||
|
ARRAY [G]
|
||||||
LIST [G]
|
LIST [G]
|
||||||
LINKED_LIST [G]</code>
|
LINKED_LIST [G]</code>
|
||||||
|
|
||||||
These classes describe data structures -- arrays, lists without commitment to a specific representation, lists in linked representation -- containing objects of a certain type. The formal generic parameter <code>G</code> denotes this type.
|
These classes describe data structures -- arrays, lists without commitment to a specific representation, lists in linked representation -- containing objects of a certain type. The formal generic parameter <code>G</code> denotes this type.
|
||||||
|
|
||||||
A class such as these doesn't quite yet describe a type, but a type template, since <code> G </code> itself denotes an unknown type. To derive a directly usable list or array type, you must provide a type corresponding to <code>G</code>, called an '''actual generic parameter'''; this may be either an expanded type, including basic types such as <code>INTEGER</code>, or a reference type. Here are some possible generic derivations:
|
A class such as these doesn't quite yet describe a type, but a type template, since <code> G </code> itself denotes an unknown type. To derive a directly usable list or array type, you must provide a type corresponding to <code>G</code>, called an '''actual generic parameter'''; this may be either an expanded type, including basic types such as <code>INTEGER</code>, or a reference type. Here are some possible generic derivations:
|
||||||
<code>il: LIST [INTEGER]
|
<code>
|
||||||
|
il: LIST [INTEGER]
|
||||||
aa: ARRAY [ACCOUNT]
|
aa: ARRAY [ACCOUNT]
|
||||||
aal: LIST [ARRAY [ACCOUNT]]</code>
|
aal: LIST [ARRAY [ACCOUNT]]</code>
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,12 @@ For the system to be valid, it must include all the classes which the root '''ne
|
|||||||
|
|
||||||
For a library we don't need to specify a root. If we want to make sure that every class in a library compiles fine we can specify that we want all classes to be the root.
|
For a library we don't need to specify a root. If we want to make sure that every class in a library compiles fine we can specify that we want all classes to be the root.
|
||||||
|
|
||||||
The Eiffel method suggests grouping related classes (typically 5 to 40 classes) into collections called '''clusters'''. A universe is then a set of clusters. For example the EiffelBase library is divided into clusters corresponding each to a major category of data structure: <code> lists </code>, <code> tables </code>, <code> iteration </code> and so on. You can nest clusters, using for example EiffelBase, with its own subclusters as listed, as a cluster of your system.
|
The Eiffel method suggests grouping related classes (typically 5 to 40 classes) into collections called '''clusters'''. A universe is then a set of clusters. For example the EiffelBase library is divided into clusters corresponding each to a major category of data structure: <code>lists</code>, <code>tables</code>, <code>iteration</code>, and so on. You can nest clusters, using for example EiffelBase, with its own subclusters as listed, as a cluster of your system.
|
||||||
|
|
||||||
How will you specify a universe? Any Eiffel implementation can use its own conventions. EiffelStudio applies a simple policy: <br/>
|
How will you specify a universe? Any Eiffel implementation can use its own conventions. EiffelStudio applies a simple policy: <br/>
|
||||||
* Store each class in a single file, called its class file, with a name of the form <code>name</code>.<code>e</code> . For clarity, <code>name</code> should be the lower-case version of the class name, although this is a style rule, not a requirement.
|
* Store each class in a single file, called its class file, with a name of the form <code>name</code>.<code>e</code> . For clarity, <code>name</code> should be the lower-case version of the class name, although this is a style rule, not a requirement.
|
||||||
* Put all the class files of a cluster into a single directory (folder on Windows), called its cluster directory.
|
* Put all the class files of a cluster into a single directory (folder on Windows), called its cluster directory.
|
||||||
{{note|It is desirable for clarity, as a style rule, to separate clusters that directly contain classes ("terminal clusters") from those that have subclusters. Cluster directories will then contain class files or cluster subdirectories, but not both. }}
|
{{note|It is desirable for clarity, as a style rule, to separate clusters that directly contain classes ("terminal clusters") from those that have subclusters. Cluster directories will then contain class files or cluster subdirectories, but not both. }}
|
||||||
|
|
||||||
* To specify a system, it suffices to provide a list of cluster directories, along with the name of the root class and root procedure. The universe consists of the classes contained in all the class files in the listed cluster directories.
|
* To specify a system, it suffices to provide a list of cluster directories, along with the name of the root class and root procedure. The universe consists of the classes contained in all the class files in the listed cluster directories.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ Eiffel is strongly typed for readability and reliability. Every entity is declar
|
|||||||
|
|
||||||
Any type <code>T</code> is based on a class, which defines the operations that will be applicable to instances of <code>T</code>. The difference between the two categories of type affects the semantics of an entity <code>x</code> declared of type <code>T</code>: for a reference type, the most common case, possible values for <code>x</code> are references to objects; for an expanded type, the values are objects. In both cases, the type rules guarantee that the objects will be instances of <code>T</code>.
|
Any type <code>T</code> is based on a class, which defines the operations that will be applicable to instances of <code>T</code>. The difference between the two categories of type affects the semantics of an entity <code>x</code> declared of type <code>T</code>: for a reference type, the most common case, possible values for <code>x</code> are references to objects; for an expanded type, the values are objects. In both cases, the type rules guarantee that the objects will be instances of <code>T</code>.
|
||||||
|
|
||||||
A non-expanded class such as <code> ACCOUNT </code> yields a reference type. As a result, an entity of type <code> ACCOUNT </code>, such as <code> acc </code> in the earlier client example (see the declaration of <code> acc </code> and the accompanying picture as given on page [[Invitation to Eiffel|6]] ), denotes possible run-time references to objects of type <code> ACCOUNT </code>.
|
A non-expanded class such as <code>ACCOUNT</code> yields a reference type. As a result, an entity of type <code>ACCOUNT</code>, such as <code>acc</code> in the earlier client example (see the declaration of <code>acc</code> and the accompanying picture as given in [[4 Classes|section 4]] ), denotes possible run-time references to objects of type <code>ACCOUNT</code>.
|
||||||
|
|
||||||
In contrast, the value of an entity <code>acc</code> declared of type <code>expanded ACCOUNT</code> is an object such as the one shown on the figure below, with no reference. The only difference with the earlier figure is that the value of <code>acc</code> is now an <code>ACCOUNT</code> object, not a reference to such an object. No creation instruction is needed in this case. (The figure does not show the <code>PERSON</code> object to which the <code>owner</code> field of the <code>ACCOUNT</code> object -- itself a reference -- is attached.)
|
In contrast, the value of an entity <code>acc</code> declared of type <code>expanded ACCOUNT</code> is an object such as the one shown on the figure below, with no reference. The only difference with the earlier figure is that the value of <code>acc</code> is now an <code>ACCOUNT</code> object, not a reference to such an object. No creation instruction is needed in this case. (The figure does not show the <code>PERSON</code> object to which the <code>owner</code> field of the <code>ACCOUNT</code> object -- itself a reference -- is attached.)
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ In contrast, the value of an entity <code> acc </code> declared of type <code>ex
|
|||||||
[[Image:invitation-3]]
|
[[Image:invitation-3]]
|
||||||
|
|
||||||
|
|
||||||
An important group of expanded types, based on library classes, includes the basic types <code> CHARACTER, DOUBLE, REAL, INTEGER </code> and <code>BOOLEAN</code>. Clearly, the value of an entity declared of type <code> INTEGER </code> should be an integer, not a reference to an object containing an integer value. Operations on these types are defined by prefix and infix operators such as "+" and "<".
|
An important group of expanded types, based on library classes, includes the basic types <code>CHARACTER, DOUBLE, REAL, INTEGER,</code> and <code>BOOLEAN</code>. Clearly, the value of an entity declared of type <code>INTEGER</code> should be an integer, not a reference to an object containing an integer value. Operations on these types are defined by prefix and infix operators such as "+" and "<".
|
||||||
|
|
||||||
As a result of these conventions, the type system is uniform and consistent: all types, including the basic types, are defined from classes, either as reference types or as expanded types.
|
As a result of these conventions, the type system is uniform and consistent: all types, including the basic types, are defined from classes, either as reference types or as expanded types.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user