merge changes from branch 17.05 onto trunk

git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@1941 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
eiffel-org
2018-02-06 13:41:39 +00:00
parent 0b47147042
commit 265a446dab
14 changed files with 293 additions and 307 deletions

View File

@@ -55,7 +55,7 @@ Another thought might be that we could just have the compiler do all the work fo
So, all of this boils down to the fact that we have to take some actions that help the compiler along. That's what the following are about.
===Certified Attachment Patterns (CAPs)===
==Certified Attachment Patterns (CAPs)==
We know that in the context of certain code patterns, it is clear that it would be impossible for a reference to be void. These patterns are identified and we call them CAPs, short for Certified Attachment Patterns. Here is a very straightforward example expressed in a syntax that should be familiar to all Eiffel developers:
<code>
@@ -73,7 +73,7 @@ It is important to understand that in this example (and with other CAPs), <code>
{{note|You will find more useful information about CAPs in [[Creating a new void-safe project#More about CAPs|More about CAPs]]. Learn how certain code patterns are determined to be CAPs in [[What makes a Certified Attachment Pattern]]. }}
===The ''attached syntax'' (object test)===
==The ''attached syntax'' (object test)==
For the purposes of void-safety, the '''attached syntax''' does double duty for us. It allows us to make certain that a reference is attached, and it provides us a safe way to access objects that are attached to class attributes.
@@ -100,7 +100,7 @@ In the example above, <code>x</code> is tested to make certain that it is attach
One way to make sure we comply with the target rule would be always use a CAP or the attached syntax every time we want to apply a feature to a referenced object. That might work, but it falls among the impractical approaches to the problem ... it would break a very high percentage of existing Eiffel code, not to mention cluttering things up quite a bit.
===Types as "attached" or "detachable"===
==Types as "attached" or "detachable"==
Rather than trying to protect every feature call, Eiffel allows us to declare any variable as being of an '''attached type'''. This is an important extension to the Eiffel type system.
@@ -126,7 +126,7 @@ This doesn't mean that on every declaration you must put either an ''attached ma
In Eiffel then, all declarations will have types that are either '''attached''' or '''detachable'''. As a result, we need only use CAPs and the attached syntax with detachable types. So the important thing to remember is that ''direct access to class attributes of detachable types is never void-safe.''
====Attachment and conformance====
===Attachment and conformance===
The distinction between attached and detachable types results in a small but important addition to the rules of conformance. Because variables declared as attached types can never be void, then it is important not to allow any assignment of a detachable source to an attached target. However, assigning an attached source to a detachable target is permissible. The following code shows both cases (as described earlier, class types are attached by default).
<code>
@@ -140,7 +140,7 @@ The distinction between attached and detachable types results in a small but imp
</code>
===Initialization rule===
==Initialization rule==
If we have attached types, then we can assume variables declared of these types, once attached, will always be attached. But how do they get attached in the first place? That's what the initialization rule is all about.
@@ -173,7 +173,7 @@ Still, it's not too hard to understand the basics of initializing variables of a
* A variable is considered properly set if it is '''self-initializing'''. What it means to be self-initializing is explained below.
===Self-initializing attributes===
==Self-initializing attributes==
A self-initializing attribute is guaranteed to have a value when accessed at run time. Declarations of self-initializing attributes are characterized by the use of the code that follows the <code>attribute</code> keyword. The code is executed to initialize the attribute in the case that the attribute is accessed prior to being initialized in any other way.
@@ -188,7 +188,7 @@ So, self-initializing attributes are ordinary attributes, with the restriction t
In the example above, the attribute <code>value</code> will be attached to an object of type <code>STRING</code>, in fact, the empty string, if no other initialization occurs before the first access of <code>value</code>.
===Rule for conformance===
==Rule for conformance==
You will remember that the Eiffel type system dictates that an assignment instruction:
<code>
@@ -206,7 +206,7 @@ The same goes for routine calls. In a call:
</code>
where <code>x</code> is the formal argument for <code>r</code>, then if x is of an attached type, then y must be of an attached type.
===Stable attributes===
==Stable attributes==
Stable attributes are really stable ''detachable'' attributes, as adding the concept of stability is meaningful only for detachable attributes. Declaring a detachable attribute as stable, means that it behaves like a detachable attribute except that its assignment rules mimic those of attached attributes. In other words, a stable attribute does not need to be attached during object creation the way that attributes declared as attached must. But like attached type attributes, stable attributes can never be the target of an assignment in which the source is <code>Void</code> or a detachable type.
<code>
@@ -221,7 +221,7 @@ This means that even though stable attributes do not need to be initialized like
Stable attributes are also interesting in that they are the only exception to the rule given above in the [[Void-safety: Background, definition, and tools#Certified Attachment Patterns (CAPs)|CAPs section]] that stated that direct access to attributes cannot be protected by a CAP. A stable attribute can be used under the protection of a CAP. This is because once a stable attribute has an object attached, it can never again be set to <code>Void</code>. So there's no worry about having the attribute's state going unexpectedly from attached to non-attached because of the actions of other routines or threads.
===Rule for generic parameters===
==Rule for generic parameters==
Generic classes provide another question. A generic class like
<code>
@@ -265,7 +265,7 @@ class C [G -> attached ANY]
</code>
then <code>x</code> in this class <code>G</code> represents an attached type. Consequently, the actual generic type in any derivation must be attached ... and feature calls on <code>x</code> are safe.
===Rule for ARRAYs===
==Rule for ARRAYs==
The rule for generic parameters applies to all generic types ... except <code>ARRAYs</code>. In the typical creation of an <code>ARRAY</code>, we would provide a minimum and maximum index.
<code>
@@ -285,7 +285,3 @@ The first argument is an object of the actual generic type, in this case an empt
For more detail on void-safe use of arrays and other generic classes, see the section: [[Creating a new void-safe project#Using generic classes|Using generic classes]].

View File

@@ -66,7 +66,7 @@ Eiffel consists of:
**Provides multiple views of your product
***Views for different life-cycle phases and developer roles
***Graphical views
**Features automated generation HTML and XML documentation
**Features automated generation of HTML and XML documentation
*'''The Eiffel Libraries'''
**Contain rich, time-tested, multi-platform components

View File

@@ -51,7 +51,7 @@ Among the features of <code>ROUTINE</code> and its descendants the most importan
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 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
integral (f: FUNCTION [TUPLE [REAL], REAL]; low, high: REAL): REAL
-- Integral of `f' over the interval [`low', `high']
require
meaningful_interval: low <= high
@@ -120,7 +120,7 @@ In the agent <code>agent record_city (name, population, ?, ?)</code>, we say tha
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]]
PROCEDURE [TUPLE [INTEGER, INTEGER]]
</code>
where the tuple type specifies the open operands.
@@ -241,6 +241,8 @@ Inline agents are interesting also as an implementation of the notion of [http:/
Agents provide a welcome complement to the other mechanisms of Eiffel. They do not conflict with them but, when appropriate -- as in the examples sketched in this section -- provide clear and expressive programming schemes, superior to the alternatives.
Compatibility note: earlier versions of the agent classes (ROUTINE, PROCEDURE, FUNCTION, PREDICATE) had an extra initial generic parameter, for which ANY was generally used. The compiler has been engineered to accept the old style in most cases.
{{SeeAlso|[[Event Programming with Agents]] }}

View File

@@ -7,7 +7,7 @@ Such objects are called the '''direct instances''' of the class. Classes and obj
{{info|"Object-Oriented" is a misnomer; "Class-Oriented Analysis, Design and Programming" would be a more accurate description of the method. }}
To see what a class looks like, let us look at a simple example, <code>ACCOUNT</code>, which describes bank accounts. But before exploring the class itself it is useful to study how it maybe used by other classes, called its '''clients'''.
To see what a class looks like, let us look at a simple example, <code>ACCOUNT</code>, which describes bank accounts. But before exploring the class itself it is useful to study how it may be used by other classes, called its '''clients'''.
A class <code>X</code> may become a client of <code>ACCOUNT</code> by declaring one or more '''entities''' of type <code>ACCOUNT</code>. Such a declaration is of the form:
<code>acc: ACCOUNT</code>

View File

@@ -143,7 +143,7 @@ Under EiffelStudio you may also set up compilation options, for the whole system
This ability to check assertions provides a powerful testing and debugging mechanism, in particular because the classes of the EiffelBase Libraries, widely used in Eiffel software development, are protected by carefully written assertions.
Run-time monitoring, however, is only one application of assertions, whose role as design and documentation aids, as part of theory of Design by Contract&#153;, exerts a pervasive influence on the Eiffel style of software development.
Run-time monitoring, however, is only one application of assertions, whose role as design and documentation aids, as part of the theory of Design by Contract&#153;, exerts a pervasive influence on the Eiffel style of software development.

View File

@@ -1,7 +1,7 @@
[[Property:title|I2E: Event-Driven Programming and Agents]]
[[Property:weight|-7]]
[[Property:uuid|16fdab60-ae42-1bb8-f4bb-89e34d18a842]]
The division of roles in object technology is clear: of the two principal constituents of a system, object types and operations, the first dominates. Classes, representing object types, determines the structure of the software; every routine, representing an operations, belongs to a class.
The division of roles in object technology is clear: of the two principal constituents of a system, object types and operations, the first dominates. Classes, representing object types, determines the structure of the software; every routine, representing an operation, belongs to a class.
In some circumstances it is useful to define an object that denotes an operation. This is especially useful if you want to build an object structure that refers to operations, so that you can later traverse the structure and execute the operations encountered. A typical application is '''event-driven programming''' for Graphical User Interfaces (GUI), including Web programming. In GUI programming you will want to record properties of the form
<code>

View File

@@ -8,7 +8,9 @@
* Implemented once manifest strings. They can be used at the same places where normal manifest strings can be used, e.g.:
<code>s := once "abc"
io.put_string (once "Hello World!")</code>
Once manifest strings are not created every time they are accessed. Instead one instance is created at the first access and then it is reused for subsequent accesses.==What's new==
Once manifest strings are not created every time they are accessed. Instead one instance is created at the first access and then it is reused for subsequent accesses.
==What's new==
{{seealso|[[Differences between standard ECMA-367 and Eiffel Software implementation|Differences between standard ECMA-367 and Eiffel Software implementation]] }}
* Implemented once manifest strings. They can be used at the same places where normal manifest strings can be used, e.g.:

View File

@@ -37,7 +37,7 @@ The code generated for the selected type is quite straightforward, an example:
[[Image:feature-wizard-complextype]]
<code>
new_feature: FUNCTION [ANY, TUPLE [INTEGER], BOOLEAN]
new_feature: FUNCTION [TUPLE [INTEGER], BOOLEAN]
</code>

View File

@@ -1,7 +1,6 @@
[[Property:title|EiffelBase Tutorial]]
[[Property:weight|-2]]
[[Property:uuid|d540615d-802b-8e12-af74-4d01d1fc4760]]
==EiffelBase Tutorial==
Learn about the EiffelBase library.

View File

@@ -111,7 +111,7 @@ For example, a region might be locked because of a controlled argument somewhere
There is a workaround to disable lock passing for a specific call:
<code>
async_call (a_procedure: separate PROCEDURE [ANY, TUPLE])
async_call (a_procedure: separate PROCEDURE [TUPLE])
do
a_procedure.call (Void)
end

View File

@@ -1,13 +1,9 @@
[[Property:title|SCOOP implementation]]
[[Property:weight|9]]
[[Property:uuid|eeb07907-e036-f3d6-5297-a7c44cfd1900]]
The implementation of SCOOP within EiffelStudio varies from the definition as it has been presented in publications during the model's evolution.
Some of the differences stem from the reality that SCOOP systems could be optimized for performance, including maximizing concurrency. For example, even though the SCOOP rules state that a separate call to a query is synchronous, i. e., the calling processor waits until the query completes before proceeding, if a static analysis can show that the wait is not necessary to the proper functioning of the remainder of the calling routine, then the call to the query can be done asynchronously.
In other ways, particularly for early versions, the EiffelStudio implementation may not cover all the goals of SCOOP as stated in the various publications. Certain elements that are defined in the SCOOP descriptions may not yet be present, or only partially implemented in the EiffelStudio implementation.
The differences between the EiffelStudio implementation of SCOOP and current and previous definitions of the SCOOP model are shown below.
The implementation of SCOOP is the result of many years of design and refinement of the model. This page describes specific properties of its current state, in particular ways in which it differs from some of the earlier publications about the model.
=Known limitations=
@@ -15,44 +11,18 @@ The differences between the EiffelStudio implementation of SCOOP and current and
==Supported concurrency mechanisms==
Although the SCOOP model can support virtually any underlying concurrency mechanism, the initial SCOOP implementation in EiffelStudio version 6.8 supports only one executable, using multiple process threads as SCOOP [[Concurrent programming with SCOOP#Processors|processors]].
At the core of the SCOOP model lies the notion of [[Concurrent programming with SCOOP#Processors|processor]]: a mechanism that can execute instructions sequentially. As a general model covering many forms of concurrency, SCOOP allows many possible implementations of this concept. In the EiffelStudio implementation, processors are implemented as <em>threads</em> of the operating system.
==Maximum number of SCOOP processors==
In the initial release, the allowable maximum number of SCOOP processors per system is 1024.
The maximum number of SCOOP processors per system is currently 1024.
==Separate anchored types==
Applicable prior to revision number 86657:
Separate status for anchored types is not supported properly. So declarations of the form:
<code>
my_entity: separate like my_query
</code>
and
<code>
my_entity: separate like Current
</code>
should be used only if you are using revision 86657 or later.
Also, if you use an anchored declaration such as:
<code>
my_entity: like my_query
</code>
and the type of <code>my_query</code> is <code>separate</code>, you should make sure you are using revision 86657 or later.
==Agents targeted to objects of separate types==
In version 6.8, agents targeted on separate objects are not supported.
Agents targeted on separate objects are currently not supported.
=Workarounds=
@@ -101,7 +71,7 @@ If the agent does not take any arguments, you must pass Void, otherwise the comp
is on the same processor as the caller and thus triggers lock passing (see [[Asynchronous Calls]]):
<code>
do_call (proc: separate PROCEDURE [ANY, TUPLE])
do_call (proc: separate PROCEDURE [TUPLE])
do
proc.call (Void)
end
@@ -110,7 +80,7 @@ do_call (proc: separate PROCEDURE [ANY, TUPLE])
If the agent does take arguments, things get a bit more tricky. If the call must be asynchronous, you have to do a workaround with the feature <code>{ROUTINE}.empty_operands</code> like this:
<code>
do_call (a_procedure: separate PROCEDURE [ANY, TUPLE[separate STRING]]; a_string: separate STRING)
do_call (a_procedure: separate PROCEDURE [TUPLE[separate STRING]]; a_string: separate STRING)
local
l_tuple: separate TUPLE [separate STRING]
do

View File

@@ -36,7 +36,7 @@ Note that for performance reasons it is usually better to use predefined criteri
===Agent Criteria===
An agent criterion will filter the objects according to the result of an agent applied to them.
The criterion is initialized with an agent of type <e>PREDICATE [ANY, TUPLE [ANY]]</e>.
The criterion is initialized with an agent of type <e>PREDICATE [TUPLE [ANY]]</e>.
There should be either an open target or a single open argument, and the type of the objects in the query result should conform to the agent's open operand.
==Creating criteria objects==
@@ -57,7 +57,7 @@ feature -- Creating a criterion
-- containing either a single PREDICATE or three
-- values of type [STRING, STRING, ANY].
new_agent (a_predicate: PREDICATE [ANY, TUPLE [ANY]]): PS_CRITERION
new_agent (a_predicate: PREDICATE [TUPLE [ANY]]): PS_CRITERION
-- Creates an agent criterion.
new_predefined (object_attribute: STRING; operator: STRING; value: ANY): PS_CRITERION

View File

@@ -3,4 +3,15 @@
[[Property:uuid|4ddb235c-fea6-ee00-05af-6493e2c652a7]]
== Network communication solutions==
There are a few network related library either coming with EiffelStudio delivery, or available as iron package:
* '''EiffelNet''':
: manipulation of sockets, network addresses, IPv4, IPv6. But also basic limited implementation for a few protocols. <code lang="shell">$ISE_LIBRARY/library/net/net.ecf</code>
* '''ZeroMQ''':
: wrapping for the [http://zeromq.org/ ZeroMQ] Distributed Messaging . [https://svn.eiffel.com/eiffelstudio/trunk/Src/library/zeromq]
* '''http_client''':
: simple web client to send http (GET, POST, ...) request and receive associated response. <code lang="shell">$ISE_LIBRARY/contrib/library/network/http_client/http_client.ecf</code>

View File

@@ -7,13 +7,13 @@ The implementation of agents is an advanced topic, but you do not have to unders
==Objects that Represent Operations==
Object technology is based on the idea that when we model real world objects, we model them based on the things that they have and what they can do ... their properties and their operations. The operations in Eiffel are the routines, i.e., the functions and procedures, of classes. Operations are not objects.
Object technology is based on the idea that when we model systems based on objects, representing the "things" they manipulate. As to operations on these objects, they appear in the corresponding classes, as routines (functions and procedures). Operations are not objects.
Having said that, it is sometimes desirable for us to model operations. We do this in the same fashion that we model other concepts: statically as classes, and as objects at runtime.
Sometimes, on the other hand, the "things" we model with our objects could represent operations. For example, we might want to build a list of tasks to be performed later; each task is defined by a routine. Each of the objects in the list will represent the corresponding routine.
An object that represents an operation is called an agent.
Such an object, representing an operation, is called an agent.
If we can have a runtime object that represents an operation, then we can place the object in the structure of another object, where at some later time, a client can cause the associated operation to execute.
If we can have a run-time object that represents an operation, then we can place the object in the structure of another object, where at some later time, a client can cause the associated operation to execute.
This is a very desirable model for event driven processing, like graphical user interfaces. The operations that are executed when a user take some action like clicking on a button, could be represented by agents. When the user interface element is initialized, agents that represent the action routines are stored within the interface element. Then at the time that an event, say a button click, occurs, the agents for that event are retrieved and their associated operations are executed.
@@ -23,9 +23,9 @@ Another area in which agents are commonly used is in traversing data structures.
We know that there are two types of routines in Eiffel, functions and procedures.
Not surprisingly, the implementation of agents relies on three classes in the Base Library. Class <code>ROUTINE</code>, and its heirs <code>FUNCTION</code> and <code>PROCEDURE</code>.
The implementation of agents correspondingly relies on three classes in the Base Library: class <code>ROUTINE</code> for the general notion, and its heirs <code>FUNCTION</code>, with and <code>PROCEDURE</code>. In addition, <code>PREDICATE</code>, an heir of <code>FUNCTION</code> , covers the particular case of a function returning a boolean result.
When you use an agent from a client routine, you will be building an instance of either <code>FUNCTION</code> or <code>ROUTINE</code>. This happens implicitly as you will see.
When you use an agent from a client routine, you will be building an instance of either <code>FUNCTION</code> or <code>ROUTINE</code>.
==Using Agents==
@@ -42,10 +42,10 @@ It is important to understand that <code>step_forward</code> does not get applie
In this example, the routine "<code>step_forward</code>" on which the agent is based takes no arguments. If you drilled down into the workings of this example you would find that class that implements the feature <code>extend</code> is class <code>EV_NOTIFY_ACTION_SEQUENCE</code>. You would also see that the signature for the feature <code>extend</code> is as essentially as follows.
<code>
extend (v: PROCEDURE [ANY, TUPLE])
extend (v: PROCEDURE [TUPLE])
</code>
We don't have to know too much about the workings of agents to see that "<code>extend</code>" takes an argument <code>v</code> which is of type <code>PROCEDURE</code>. It turns out that the actual generic parameter <code>TUPLE</code> represents the set of "open" arguments. In this case, extend is expecting an agent which has no open arguments.
We don't have to know too much about the workings of agents to see that "<code>extend</code>" takes an argument <code>v</code> which is of type <code>PROCEDURE</code>. The actual generic parameter <code>TUPLE</code> represents the set of "open" arguments. In this case, <code>extend</code> is expecting an agent with no open arguments.
===Open and Closed Arguments===
@@ -53,7 +53,7 @@ It is this business of open and closed arguments which really makes agents remar
Suppose a class has a feature declared as shown below.
<code>
my_procedure: PROCEDURE [ANY, TUPLE]
my_procedure: PROCEDURE [TUPLE]
</code>
Then what can be assigned to <code>my_procedure</code>?. An agent, of course. Say the class has procedures as follows.
@@ -76,14 +76,14 @@ Then the following assignment is valid.
my_procedure := agent no_argument_procedure
</code>
What this means is that the agent created and associated with the procedure <code>no_argument_procedure</code> must conform to the type <code>PROCEDURE [ANY, TUPLE]</code>. The feature <code>my_procedure</code> (which is of type <code>PROCEDURE [ANY, TUPLE]</code>) can be attached at runtime to an agent representing a procedure with no open arguments, which indeed is what <code>no_argument_procedure</code> is.
What this means is that the agent created and associated with the procedure <code>no_argument_procedure</code> must conform to the type <code>PROCEDURE [TUPLE]</code>. The feature <code>my_procedure</code> (which is of type <code>PROCEDURE [TUPLE]</code>) can be attached at runtime to an agent representing a procedure with no open arguments, which indeed is what <code>no_argument_procedure</code> is.
Now let's turn our attention to the other procedure <code>two_argument_procedure</code>. You might think that because it takes two arguments, that you would not be able to build an agent from it which could be assigned to the attribute <code>my_procedure</code>. But you can do it by closing the two arguments at the time that the agent is created, as in the following.
<code>
my_procedure := agent two_argument_procedure (1, 2) -- Is Valid
</code>
What happens here is that values are fixed for those arguments at the time that the agent, an object of type <code>PROCEDURE [ ANY, TUPLE]</code> is created.
What happens here is that values are fixed for those arguments at the time that the agent, an object of type <code>PROCEDURE [ TUPLE]</code> is created.
So this is the wonderful thing about agents. A routine which will be represented as an agent does not have to be an exact fit for the expected signature. By closing some arguments at agent creation, you have effectively produced a new and conforming routine.
@@ -133,7 +133,7 @@ Now suppose we want to print the values of all the strings in <code>my_strings</
The availability of agents gives us new options. <code>LINKED_LIST</code> has a feature <code>do_all</code> which comes to it from its ancestor <code>LINEAR</code>. The <code>do_all</code> feature's signature looks like this:
<code>
do_all (action: PROCEDURE [ANY, TUPLE [G]])
do_all (action: PROCEDURE [TUPLE [G]])
</code>
As an argument <code>do_all</code> takes an agent based on a procedure with one open argument which is the same type as the list items (in this class, <code>G</code> is the formal generic parameter representing the type of the items being stored). Then it traverses the list executing the routine associated with that agent and uses the current list item to satisfy the open argument.
@@ -190,8 +190,14 @@ Here again we'll use a feature of the <code>LINKED_LIST</code> class. There is a
my_list.do_if (agent print_on_new_line(?), agent {STRING}.has('!'))
</code>
The agent for the action is the same as we used earlier. We've added an agent for the test. It represents applying the <code>has</code> feature of the <code>STRING</code> class. Here the target is left open, because we want each of the strings in the list to be the target of <code>has</code>.
Compatibility note
Versions of the Kernel Library classes ROUTINE, PROCEDURE, FUNCTION and PREDICATE prior to EiffelStudio 17-05 had an extra generic parameter at the initial position; the usual actual generic parameter was ANY. It has been removed. The compiler has been engineered so that in almost all cases it will still accept the old style.