Author:halw

Date:2008-10-21T19:55:42.000000Z


git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@92 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
halw
2008-10-21 19:55:42 +00:00
parent b21bb98cb1
commit 9e103d1507
7 changed files with 279 additions and 259 deletions

View File

@@ -1,7 +1,9 @@
[[Property:title|Community]]
[[Property:weight|2]]
[[Property:uuid|75c75712-7c3e-2757-51b7-77b404471e2e]]
EiffelStudio community:
Eiffel is a community. Members of the Eiffel community can contribute to this documentation through this book.
:'''You can become a contributor!'''

View File

@@ -52,7 +52,7 @@ Among the features of <code> ROUTINE </code> and its descendants the most import
As an example of using these mechanisms, here is how the function <code>integral</code> could look like in our <code>INTEGRATOR</code> example class. The details of the integration algorithm (straight forward, and making no claims to numerical sophistication) do not matter, but you see, in the highlighted line, the place were we evaluate the mathematical function associated with <code>f</code>, by calling <code>item</code> on <code>f</code>:
<code>
integral (f: FUNCTION [ANY, TUPLE [REAL], REAL]; low, high: REAL): REAL is
integral (f: FUNCTION [ANY, TUPLE [REAL], REAL]; low, high: REAL): REAL
-- Integral of `f' over the interval [`low', `high']
require
meaningful_interval: low <= high
@@ -80,7 +80,7 @@ Function <code> integral </code> takes three arguments: the agent <code> f </cod
Result := Result + step * f.item ([x])
</code>
we don't directly pass <code> x </code> to <code> item </code>; instead, we pass a one-element tuple <code> [x] </code>, using the syntax for manifest tuples introduced in [[10 Other Mechanisms|"Tuple types", page 90]] . You will always use tuples for the argument to <code> call </code> and <code> item </code>, because these features must be applicable to any routine, and so cannot rely on a fixed number of arguments. Instead they take a single tuple intended to contain all the arguments. This property is reflected in the type of the second actual generic parameter to <code> f </code>, corresponding to <code> ARGS </code> (the formal generic parameter of <code> FUNCTION </code>): here it's <code> TUPLE [REAL] </code> to require an argument such as <code> [ x] </code>, where <code> x </code> is of type <code> REAL </code>.
we don't directly pass <code>x</code> to <code>item</code>; instead, we pass a one-element tuple <code>[x]</code>, using the syntax for manifest tuples introduced in [[10 Other Mechanisms#Tuple_types|"Tuple types"]] . You will always use tuples for the argument to <code>call</code> and <code>item</code>, because these features must be applicable to any routine, and so cannot rely on a fixed number of arguments. Instead they take a single tuple intended to contain all the arguments. This property is reflected in the type of the second actual generic parameter to <code>f</code>, corresponding to <code>ARGS</code> (the formal generic parameter of <code>FUNCTION</code>): here it's <code>TUPLE [REAL]</code> to require an argument such as <code>[ x]</code>, where <code>x</code> is of type <code>REAL</code>.
Similarly, consider the agent that the call seen above:
<code>
@@ -119,7 +119,7 @@ assuming that the information on the <code> name </code> and the <code> populati
In the agent <code>agent record_city (name, population, ?, ?)</code>, we say that these first two arguments, with their set values, are '''closed'''; the last two are '''open'''. The question mark syntax introduced by this example may only appear in agent expressions; it denotes open arguments. This means, by the way, that you may view the basic form used in the preceding examples, <code>agent your_routine</code>, as an abbreviation -- assuming your_routine has two arguments -- for <code>agent your_routine (?, ?)</code>. It is indeed permitted, to define an agent with all arguments open, to omit the argument list altogether; no ambiguity may result.
For type checking, <code> agent record_city (name, population, ?, ?) </code> and <code> agent ,your_routine </code> are acceptable in exactly the same situations, since both represent routines with two arguments. The type of both is
For type checking, <code>agent record_city (name, population, ?, ?)</code> and <code>agent your_routine (?, ?)</code> are acceptable in exactly the same situations, since both represent routines with two arguments. The type of both is
<code>
PROCEDURE [ANY, TUPLE [INTEGER, INTEGER]]
</code>
@@ -172,7 +172,7 @@ your_integer_list.do_all (agent add_to_n)
even though the two procedures used in the agents have quite different forms. We are assuming here that the first one, in class <code>ACCOUNT</code>, is something like
<code>
deposit_one_grand is
deposit_one_grand
-- Add one thousand dollars to `balance' of account.
do
balance := balance + 1000
@@ -181,7 +181,7 @@ deposit_one_grand is
so that it doesn't take an argument: it is normally called on its target, as in <code>my_account.deposit_one_grand</code>. In contrast, the other routine has an argument:
<code>
add_to_n (x: INTEGER) is
add_to_n (x: INTEGER)
-- Add `x' to the value of `total'.
do
total := total + x

View File

@@ -288,6 +288,7 @@ With the dot notation seen so far, this would imply that simple arithmetic opera
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>

View File

@@ -19,7 +19,7 @@ at the beginning of each affected routine; the first one to come in will perform
Once functions will give us shared objects. A common scheme is
<code>
console: WINDOW is
console: WINDOW
-- Shared console window
once
create Result.make (...)
@@ -38,16 +38,16 @@ The attributes studied earlier were variable: each represents a field present in
It is also possible to declare constant attributes, as in
<code>
Solar_system_planet_count: INTEGER is 9
Solar_system_planet_count: INTEGER = 9
</code>
These will have the same value for every instance and hence do not need to occupy any space in objects at execution time. (In other approaches similar needs would be addressed by symbolic constants, as in Pascal or Ada, or macros, as in C.)
What comes after the <code>is</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 is unique
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.)
@@ -70,7 +70,17 @@ which is an expression of type <code>ARRAY [INTEGER]</code>. Manifest arrays and
Eiffel has a remarkably small set of instructions. The basic computational instructions have been seen: creation, assignment, assignment attempt, procedure call, retry. They are complemented by control structures: conditional, multi-branch, loop, as well as debug and check.
A conditional instruction has the form <code>if</code> ... <code>then</code> ... <code>elseif</code> ... <code>then</code> ... <code>else</code> ... <code>end</code>. The <code>elseif</code> ... <code>then</code> ... part (of which there may be more than one) and the <code>else</code> ... part are optional. After <code>if</code> and <code>elseif</code> comes a boolean expression; after <code>then</code>, <code>elseif</code> and <code>else</code> come zero or more instructions.
A conditional instruction has the form
<code>
if ... then
...
elseif ... then
...
else
...
end
</code>
The <code>elseif</code> ... <code>then</code> ... part (of which there may be more than one) and the <code>else</code> ... part are optional. After <code>if</code> and <code>elseif</code> comes a boolean expression; after <code>then</code>, <code>elseif</code> and <code>else</code> come zero or more instructions.
A multi-branch instruction has the form
<code>
@@ -86,7 +96,7 @@ else
end
</code>
where the <code>else</code> ''inst0'' part is optional, <code>exp</code> is a character or integer expression, ''v1'', ''v1'', ... are constant values of the same type as <code>exp</code>, all different, and ''inst0'', ''inst1'', ''inst2'', ... are sequences of zero or more instructions. In the integer case, it is often convenient to use <code>unique</code> values ( [[10 Other Mechanisms|"Constant and unique attributes", page 83]] ) for the ''vi''
where the <code>else ''inst0''</code> part is optional, <code>exp</code> is a character or integer expression, ''v1'', ''v1'', ... are constant values of the same type as <code>exp</code>, all different, and ''inst0'', ''inst1'', ''inst2'', ... are sequences of zero or more instructions. In the integer case, it is often convenient to use <code>unique</code> values ( [[10 Other Mechanisms|"Constant and unique attributes", page 83]] ) for the ''vi''.
The effect of such a multi-branch instruction, if the value of <code>exp</code> is one of the ''vi'', is to execute the corresponding ''insti''. If none of the ''vi'' matches, the instruction executes ''inst0'', unless there is no <code>else</code> part, in which case it triggers an exception.
@@ -115,11 +125,16 @@ The assertion ''inv'', if present, expresses a '''loop invariant''' (not to be c
An occasionally useful instruction is <code>debug</code> <code>(</code>''Debug_key'', ... <code>)</code> ''instructions'' <code>end</code> where ''instructions'' is a sequence of zero or more instructions and the part in parentheses is optional, containing if present one or more strings, called debug keys. The EiffelStudio compiler lets you specify the corresponding <code>debug</code> compilation option: <code>yes</code>, <code>no</code>, or an explicit debug key. The ''instructions'' will be executed if and only if the corresponding option is on. The obvious use is for instructions that should be part of the system but executed only in some circumstances, for example to provide extra debugging information.
The final instruction is connected with Design by Contract&#153;. The instruction <code>check</code> ''Assertion'' <code>end</code>, where ''Assertion'' is a sequence of zero or more assertions, will have no effect unless assertion monitoring is turned on at the <code>Check</code> level or higher. If so it will evaluate all the assertions listed, having no further effect if they are all satisfied; if any one of them does not hold, the instruction will trigger an exception.
The final instruction is connected with Design by Contract&#153;. The instruction
<code>
check
Assertion
end
</code>, where Assertion is a sequence of zero or more assertions, will have no effect unless assertion monitoring is turned on at the <code>Check</code> level or higher. If so it will evaluate all the assertions listed, having no further effect if they are all satisfied; if any one of them does not hold, the instruction will trigger an exception.
This instruction serves to state properties that are expected to be satisfied at some stages of the computation -- other than the specific stages, such as routine entry and exit, already covered by the other assertion mechanisms such as preconditions, postconditions and invariants. A recommended use of <code>check</code> involves calling a routine with a precondition, where the call, for good reason, does not explicitly test for the precondition. Consider a routine of the form
<code>
r (ref: SOME_REFERENCE_TYPE) is
r (ref: SOME_REFERENCE_TYPE)
require
not_void: ref /= Void
do
@@ -130,7 +145,9 @@ r (ref: SOME_REFERENCE_TYPE) is
Because of the call to <code>some_feature</code>, the routine will only work if its precondition is satisfied on entry. To guarantee this precondition, the caller may protect it by the corresponding test, as in
<code>
if x /= Void then a.r (x) end
if x /= Void then
a.r (x)
end
</code>
but this is not the only possible scheme; for example if an <code>create x</code> appears shortly before the call we know <code>x</code> is not void and do not need the protection. It is a good idea in such cases to use a <code>check</code> instruction to document this property, if only to make sure that a reader of the code will realize that the omission of an explicit test (justified or not) was not a mistake. This is particularly appropriate if the justification for not testing the precondition is less obvious. For example <code>x</code> could have been obtained, somewhere else in the algorithm, as <code>clone (y)</code> for some <code>y</code> that you know is not void. You should document this knowledge by writing the call as
@@ -155,7 +172,7 @@ This raises the issue of backward compatibility: how to move forward with a bett
The notion of obsolete class and feature helps address this issue. By declaring a feature as <code>obsolete</code>, using the syntax
<code>
enter (i: INTEGER; x: G) is
enter (i: INTEGER; x: G)
obsolete
"Use ` put (x, i)' instead "
require
@@ -253,8 +270,7 @@ Features available on tuple types include <code>count: INTEGER</code>, yielding
Tuples are appropriate when these are the only operations you need, that is to say, you are using sequences with no further structure or properties. Tuples give you "anonymous classes" with predefined features <code>count</code>, <code>item</code> and <code>put</code>. A typical example is a general-purpose output procedure that takes an arbitrary sequence of values, of arbitrary types, and prints them. It may simply take an argument of type <code>TUPLE</code>, so that clients can call it under the form
<code>
write ([ ''your_integer'' , ''your_real'', ''your_account''])
write ([your_integer, your_real, your_account])
</code>
As soon as you need a type with more specific features, you should define a class.

View File

@@ -1,5 +1,6 @@
[[Property:title|Once features in multithreaded mode]]
[[Property:weight|4]]
[[Property:uuid|5578da29-7603-b501-1a7d-305d20fd6485]]
==Manipulating Once features in multithreaded mode==
Eiffel introduced the powerful mechanism of once routines. A once routine has a body that will be executed only once, at the first call. Subsequent calls will have no further effect and, in the case of a function, will return the same result as the first. This provides a simple way of sharing objects in an object-oriented context.
@@ -23,7 +24,7 @@ Here is what you will do to implement a once per process feature:
class
TEST_ONCE_PER_PROCESS
feature
feature -- Access
object_per_thread: OBJECT is
-- Once per thread.