mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-07 07:12:25 +01:00
Author:halw
Date:2008-10-19T17:24:57.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@89 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -267,21 +267,29 @@ Following the principle of Uniform Access (mentioned earlier in the section ''Ob
|
||||
|
||||
In the case of a routine with arguments -- procedure or function -- the routine will be declared, in its class, as
|
||||
<code>
|
||||
feature (formal1: TYPE1; ...)
|
||||
some_feature (formal_1: TYPE_1; ...)
|
||||
do
|
||||
...
|
||||
end
|
||||
</code>
|
||||
|
||||
meaning that, at the time of each call, the value of each formal will be set to the corresponding actual ( <code>formal1</code> to <code>argument1</code> and so on).
|
||||
meaning that, at the time of each call, the value of each formal will be set to the corresponding actual (<code>formal_1</code> to <code>argument_1</code> and so on).
|
||||
|
||||
In the routine body, it is not permitted to change the value of a formal argument, although it is possible to change the value of an attached object through a procedure call such as <code> formal1.some_procedure ( ... )</code> .
|
||||
In the routine body, it is not permitted to change the value of a formal argument, although it is possible to change the value of an attached object through a procedure call such as <code>formal_1.some_procedure ( ... )</code> .
|
||||
|
||||
==Infix and prefix notation==
|
||||
|
||||
Basic types such as <code>INTEGER</code> are, as noted, full-status citizens of Eiffel's type system, and so are declared as classes (part of the Kernel Library). <code>INTEGER</code>, for example, is characterized by the features describing integer operations: plus, minus, times, division, less than, and so on.
|
||||
|
||||
With the dot notation seen so far, this would imply that simple arithmetic operations would have to be written with a syntax such as <code>i.plus (j)</code> instead of the usual <code>i + j</code>. This would be awkward. Infix and prefix features solve the problem, reconciling the object-oriented view of computation with common notational practices of mathematics. The addition function is declared in class <code>INTEGER</code> as
|
||||
With the dot notation seen so far, this would imply that simple arithmetic operations would have to be written with a syntax such as
|
||||
<code>
|
||||
i.plus (j)
|
||||
</code>
|
||||
instead of the usual
|
||||
<code>
|
||||
i + j
|
||||
</code>
|
||||
This would be awkward. Infix and prefix features solve the problem, reconciling the object-oriented view of computation with common notational practices of mathematics. The addition function is declared in class <code>INTEGER</code> as
|
||||
<code>
|
||||
infix "+" (other: INTEGER): INTEGER
|
||||
do
|
||||
@@ -293,7 +301,10 @@ Such a feature has all the properties and prerogatives of a normal "identifier"
|
||||
|
||||
Predefined library classes covering basic types such as <code>INTEGER</code>, <code>CHARACTER</code>, <code>BOOLEAN</code>, <code>REAL</code>, <code>DOUBLE</code> are known to the Eiffel compiler, so that a call of the form <code>j + i</code>, although conceptually equivalent to a routine call, can be processed just as efficiently as the corresponding arithmetic expression in an ordinary programming language. This brings the best of both worlds: conceptual simplicity, enabling Eiffel developers, when they want to, to think of integers and the like as objects; and efficiency as good as in lower-level approaches.
|
||||
|
||||
Infix and prefix features are available to any class, not just the basic types' predefined classes. For example a graphics class could use the name <code>infix "|-|"</code> for a function computing the distance between two points, to be used in expressions such as <code>point1 |-| point2</code> .
|
||||
Infix and prefix features are available to any class, not just the basic types' predefined classes. For example a graphics class could use the name <code>infix "|-|"</code> for a function computing the distance between two points, to be used in expressions such as
|
||||
<code>
|
||||
point1 |-| point2
|
||||
</code>
|
||||
|
||||
==Type declaration==
|
||||
|
||||
@@ -412,7 +423,7 @@ To copy an object, use
|
||||
</code>
|
||||
which assumes that both <code>x</code> and <code>y</code> are non-void, and copies the contents of <code>y</code>'s attached object onto those of <code>x</code>'s. For expanded entities the effect is the same as that the of the assignment <code>x := y</code>.
|
||||
|
||||
An operation performing similar duty to the <code>copy</code> is <code>twin</code> . The assignment
|
||||
An operation performing similar duty to <code>copy</code> is <code>twin</code> . The assignment
|
||||
<code>
|
||||
x := y.twin
|
||||
</code>
|
||||
@@ -427,7 +438,6 @@ So, assuming both entities of reference types and <code>y</code> not void, the a
|
||||
|
||||
|
||||
To determine whether two values are equal, use the expression:
|
||||
|
||||
<code>
|
||||
x = y
|
||||
</code>
|
||||
@@ -464,7 +474,7 @@ and test whether it is void through:
|
||||
|
||||
Note that the assignment, <code>:=</code> , and the equality operators, <code>=</code>, <code>~</code>, <code>/~</code>, and <code>/=</code> , are language constructions, whereas <code>copy</code>, <code>twin</code>, <code>is_equal</code>, and <code>equal</code> are '''library features''' coming from class <code>ANY</code> .
|
||||
|
||||
<code>Void</code> is a language keyword with built-in functionality, but it is not harmful to think of <code>Void</code> as another feature declared in <code> ANY </code>, but with type of <code>NONE</code>, the "bottom" type.
|
||||
<code>Void</code> is a language keyword with built-in characteristics, but it is not harmful to imagine <code>Void</code> as another feature declared in class <code>ANY</code>, with type of <code>NONE</code>, the "bottom" type. This convenience allows any assignment of the for <code>x := Void</code> to be valid without any making exceptions to the type rules, regardless of the type of <code>x</code> .
|
||||
|
||||
Using the redefinition mechanisms to be seen in the discussion of inheritance, a class can redefine <code>copy</code> and <code>is_equal</code> to cover specific notions of copy and equality. The assertions will ensure that the two remain compatible: after <code>x.copy (y)</code> , the property <code>x .is_equal (y)</code> must always be true. The effect of <code>twin</code> will automatically follow a redefinition of <code>copy</code>, and <code>equal</code> will follow <code>is_equal</code>.
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ Within the class text, feature declarations can freely use <code>G</code> even t
|
||||
first: G
|
||||
-- Value of first list item
|
||||
|
||||
extend (val: G) is
|
||||
extend (val: G)
|
||||
-- Add a new item of value val at end of list
|
||||
...
|
||||
</code>
|
||||
@@ -45,23 +45,23 @@ Genericity reconciles extendibility and reusability with the static type checkin
|
||||
|
||||
==Arrays==
|
||||
|
||||
An example of generic class from the Kernel Library is <code>ARRAY</code> <code>[</code> <code>G</code> <code>]</code>, which describes direct-access arrays. Features include:
|
||||
* <code>put</code> to replace an element's value, as in <code>my_array</code>. <code>put</code> <code>(</code> <code>val</code>, <code>25</code> <code>)</code> which replaces by <code>val</code> the value of the array entry at index 25.
|
||||
* <code>item</code> to access an entry, as in <code>my_array</code>. <code>item</code> <code>(</code> <code>25</code> <code>)</code> yielding the entry at index 25. A synonym is <code>infix</code> <code>"@"</code>, so that you may also write more tersely, for the same result, <code>my_array</code> <code>@</code> <code>25</code>.
|
||||
An example of generic class from the Kernel Library is <code>ARRAY</code> <code>[G]</code>, which describes direct-access arrays. Features include:
|
||||
* <code>put</code> to replace an element's value, as in <code>my_array.put (val, 25)</code> which replaces by <code>val</code> the value of the array entry at index 25.
|
||||
* <code>item</code> to access an entry, as in <code>my_array.item (25)</code> yielding the entry at index 25. A synonym is <code>infix</code> <code>"@"</code>, so that you may also write more tersely, for the same result, <code>my_array</code> <code>@</code> <code>25</code> .
|
||||
* <code>lower</code>, <code>upper</code> and <code>count</code>: queries yielding the bounds and the number of entries.
|
||||
* The creation procedure <code>make</code>, as in <code>create</code> <code>my_array</code>. <code>make</code> <code>( 1, 50 )</code> which creates an array with the given index bounds. It is also possible to resize an array through <code>resize</code>, retaining the old elements. In general, the Eiffel method abhors built-in limits, favoring instead structures that resize themselves when needed, either from explicit client request or automatically.
|
||||
* The creation procedure <code>make</code>, as in <code>create my_array.make (1, 50)</code> which creates an array with the given index bounds. It is also possible to resize an array through <code>resize</code>, retaining the old elements. In general, the Eiffel method abhors built-in limits, favoring instead structures that resize themselves when needed, either from explicit client request or automatically.
|
||||
|
||||
The comment made about <code>INTEGER</code> and other basic classes applies to <code>ARRAY</code> too: Eiffel compilers know about this class, and will be able to process expressions of the form <code>my_array</code>. <code>put</code> <code>(</code> <code>val</code>, <code>25</code> <code>)</code> and <code>my_array</code> <code>@</code> <code>25</code> in essentially the same way as a C or Fortran array access -- <code>my_array</code> <code>[</code> <code>25</code> <code>]</code> in C. But it is consistent and practical to let developers treat <code>ARRAY</code> as a class and arrays as objects; many library classes in EiffelBase, for example, inherit from <code>ARRAY</code>. Once again the idea is to get the best of both worlds: the convenience and uniformity of the object-oriented way of thinking; and the efficiency of traditional approaches.
|
||||
The comment made about <code>INTEGER</code> and other basic classes applies to <code>ARRAY</code> too: Eiffel compilers know about this class, and will be able to process expressions of the form <code>my_array.put (val, 25)</code> and <code>my_array</code> <code>@</code> <code>25</code> in essentially the same way as a C or Fortran array access -- <code>my_array</code> <code>[25]</code> in C. But it is consistent and practical to let developers treat <code>ARRAY</code> as a class and arrays as objects; many library classes in EiffelBase, for example, inherit from <code>ARRAY</code>. Once again the idea is to get the best of both worlds: the convenience and uniformity of the object-oriented way of thinking; and the efficiency of traditional approaches.
|
||||
|
||||
A similar technique applies to another Kernel Library class, that one not generic: <code>STRING</code>, describing character strings with a rich set of string manipulation features.
|
||||
|
||||
==Generic derivation==
|
||||
|
||||
The introduction of genericity brings up a small difference between classes and types. A generic class <code>C</code> is not directly a type since you cannot declare an entity as being of type <code>C</code>: you must use some actual generic parameter <code>T</code> -- itself a type. <code>C</code> <code>[</code> <code>T</code> <code>]</code> is indeed a type, but class <code>C</code> by itself is only a type template.
|
||||
The introduction of genericity brings up a small difference between classes and types. A generic class <code>C</code> is not directly a type since you cannot declare an entity as being of type <code>C</code>: you must use some actual generic parameter <code>T</code> -- itself a type. <code>C</code> <code>[T]</code> is indeed a type, but class <code>C</code> by itself is only a type template.
|
||||
|
||||
The process of obtaining a type <code>C</code> <code>[</code> <code>T</code> <code>]</code> from a general class <code>C</code> is known as a '''generic derivation'''; <code>C</code> <code>[</code> <code>T</code> <code>]</code> is a '''generically derived type'''. Type <code>T</code> itself is, recursively, either a non-generic class or again a generically derived type <code>D</code> <code>[</code> <code>U</code> <code>]</code> for some <code>D</code> and <code>U</code>, as in <code>LIST</code> <code>[</code> <code>ARRAY</code> <code>[</code> <code>INTEGER</code> <code>]]</code>.)
|
||||
The process of obtaining a type <code>C</code> <code>[T]</code> from a general class <code>C</code> is known as a '''generic derivation'''; <code>C</code> <code>[T]</code> is a '''generically derived type'''. Type <code>T</code> itself is, recursively, either a non-generic class or again a generically derived type <code>D</code> <code>[U]</code> for some <code>D</code> and <code>U</code>, as in <code>LIST</code> <code>[ARRAY [INTEGER]]</code>.)
|
||||
|
||||
It remains true, however, that every type is based on a class. The base class of a generically derived type <code>C</code> <code>[</code> <code>T</code> <code>]</code> is <code>C</code>.
|
||||
It remains true, however, that every type is based on a class. The base class of a generically derived type <code>C</code> <code>[T]</code> is <code>C</code>.
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user