NICE-ESG-Libs Digest Fri, 8 Dec 95 Volume 1 : Issue 313
Today's Topics:
ARRAY proposal
NICE Eiffel Standards Group -- Library Committee Mailing List
To post to list:
NICE-ESG-Libs@atlanta.twr.com
To send mail to the Chairman of the committee:
NICE-ESG-Libs-chair@atlanta.twr.com
Administrative matters (sign up, unsubscribe, mail problems, etc):
NICE-ESG-Libs-request@atlanta.twr.com
Date: Fri, 8 Dec 1995 16:52:42 -0500
From: jcm@mstr.hgc.edu
Subject: ARRAY proposal
To: NICE-ESG-Libs@atlanta.twr.com
----------
X-Sun-Data-Type: text
X-Sun-Data-Description: text
X-Sun-Data-Name: text
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 67
Please find two files attached: array.library.diffs and array.library
The second, array.library, is my proposal for the vintage 96 ARRAY class.
Or at least a starting point for such a class. As described in notes in the
file itself, I propose almost no new or different functionality. Rather
I have just tried to rigorously specify the intent of the vintage 95 ARRAY
class.
The first file. array.library.diffs (which perhaps should be read first)
shows each feature of
the vintage 95 ARRAY class followed by the proposed new version, along with
occasional notes explaining the changes. These notes are infrequent as I
think, based on earlier discussions, that most of the changes are now
self explanatory.
This proposal has benefited from numerous discussions with folks both inside
and outside this forum. I am particularly grateful to Eric Bezault, Roger
Browne, Bertrand Meyer, Richard Mitchell, Michael Schweitzer, Steve Tynor,
and others whom my addled brain forgets. Thanks also to Christine Mingins
for allowing me to post here directly to facilitate discussion.
While I would not claim that all the above are in agreement with every
comment and assertion in the proposal I think there is very strong consensus
with the exception of the feature 'to_c'. In particular there is severe
disagreement among the implementers as to the return type of this query.
Hence this proposal takes no stand on that issue. The feature 'to_c' is
included in the attached files as it appears in vintage 95, but the only
inference you should draw from this is that I do not believe the feature
should be removed. I'd like the implementers to thrash this problem out and
make their own separate motion regarding this issue when they're ready.
I have no formal standing on the library committee, but of course that
doesn't stop me from having an opinion on how things should proceed :-).
1. First I need someone to move that the proposal be accepted. If no one
steps forward soon to do this, I will ask Christine to do so ex officio.
2. I would like to see a deadline set for a vote, say four to six weeks
after the proposal has been moved. This deadline can always be extended if
discussion warrants.
3. I would like to see proposed changes made in the form of formal amendments
each of which can be discussed and voted on. This approach, I hope, satisies
both the people who feel we need to look at the big picture (in this case,
the whole ARRAY), and those who feel we need to work in small increments.
Obviously, the more amendments, the more likely the final vote on the proposal
will need to be postponed (which is fine with me as long as people are actively
discussing and voting).
4. I would like to see amendments limited to changes to _this_ proposal. In
particular, I would prefer not to see suggestions for additional features
(unless they can be shown to be tightly coupled to existing ones). The
reason for this is that opening discussion on such amendments could easily
lead to protracted discussions that would effectively kill the proposal.
I think it is important to get a well specified baseline established, after
which we can add features that build upon this base.
There have been a few comments on this forum recently about the lack of
progress and expressing concern as to how the kernel library is to evolve.
This proposal gives you a chance to participate and to have a very direct
effect on a most fundamental class. Please take full advantage.
Might I suggest you start by making a motion?
Respectfully submitted,
-- Jim McKim
----------
X-Sun-Data-Type: default
X-Sun-Data-Name: array.library.diffs
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 428
Recommended version of ARRAY with diffs from ELKS95. 12/8/95
Note: The only major changes between this version and what I believe was
generally intended in ELKS vintage95 is a new version of the 'make'
routine and the splitting of 'resize' into two features. Otherwise,
all I'm proposing here is a rigorous specification of the features in
(I hope) a readable and forthright way.
Special note: The return type of the query "to_c" is causing some controversy
among the implementers that may take some time to thrash out. This proposal
takes no stand on what that return type should be. The version listed here is
that of ELKS95.
In each case I show the original version of the feature in ELKS95 and the
proposed version. In most cases the motivation for the change is to provide
a rigorous specification for the feature in terms of the queries in the
specification set (see below).
Class ARRAY
indexing
description: "Sequences of values, all of the same type or of a conforming
one, accessible through integer indices in a contiguous interval"
class interface
ARRAY [G]
-- Basic specification set: lower, upper, item
-- Auxiliary specification set: is_equal, valid_index
creation
Original:
make (min_index, max_index: INTEGER)
-- Allocate array; set index interval to
-- min_index .. max_index; set all values to default.
-- (Make array empty if min_index > max_index.)
ensure
no_count: (min_index > max_index) implies (count = 0);
count_constraint: (min_index <= max_index) implies (count = max_index - min_index + 1)
Preferred:
make (min_index, max_index: INTEGER)
-- Allocate array; set index interval to
-- min_index .. max_index; set all values to default.
require
valid_indices: min_index <= max_index + 1
ensure
lower_initialized : lower = min_index
upper_initialized: upper = max_index
items_initialized: -- for_all i, lower..upper (item(i) = Void or else item(i) = item(i).default)
Original:
make_from_array (a: ARRAY [G])
-- Initialize from the items of a.
-- (Useful in proper descendants of class ARRAY,
-- to initialize an array-like object from a manifest array.)
Preferred:
make_from_array (a: ARRAY [G])
-- Initialize from the values of 'a'.
-- Useful in particular when 'a' is a manifest array.
-- Note: representation may be shared; to avoid sharing,
-- use as "make_from_array(clone( a ))"
require
a_not_void: a /= Void
ensure
lower_initialized : lower = a.lower
upper_initialized: upper = a.upper
items_initialized: -- for_all i, lower..upper (item(i) = a.item(i))
Note: There remains some controversy here as some implementers of this feature
share underlying representation with the copied array 'a' and others do not,
causing obvious interoperability (and perhaps other) problems. In the absence
of unanimity, the above warning seems appropriate.
feature -- Initialization
make (min_index, max_index: INTEGER)
-- Allocate array; set index interval to
-- min_index .. max_index; set all values to default.
require
valid_indices: min_index <= max_index + 1
ensure
lower_initialized : lower = min_index
upper_initialized: upper = max_index
items_initialized: -- for_all i, lower..upper (item(i) = Void or else item(i) = item(i).default)
make_from_array (a: ARRAY [G])
-- Initialize from the items of `a', possibly sharing their representation.
-- (Useful in proper descendants of class ARRAY,
-- to initialize an array-like object from a manifest array.)
require
a_not_void: a /= Void
ensure
lower_initialized : lower = a.lower
upper_initialized: upper = a.upper
items_initialized: -- for_all i, lower..upper (item(i) = a.item(i))
feature -- Access
Original:
entry (i: INTEGER): G
-- Entry at index i, if in index interval
-- (Redefinable synonym for item and infix "@".)
require
good_key: valid_index (i)
Preferred:
entry (i: INTEGER): G
-- Entry at index i.
-- (Redefinable synonym for item and infix "@".)
require
valid_index: valid_index( i )
Note: The fact that this feature is intended to be redefinable in unpredictable ways makes any postcondition problematic.
Original:
frozen item (i: INTEGER): G
-- Entry at index i, if in index interval
require
good_key: valid_index (i)
Preferred:
frozen item (i: INTEGER): G
-- Entry at index i.
require
valid_index: valid_index( i )
Original:
frozen infix "@" (i: INTEGER): G
-- Entry at index i, if in index interval
require
good_key: valid_index (i)
Preferred:
frozen infix "@" (i: INTEGER): G
-- Entry at index i.
require
valid_index: valid_index( i )
ensure
definition: Result = item( i )
feature -- Measurement
Original:
count: INTEGER
-- Number of available indices
Preferred:
count: INTEGER
-- Number of available indices
ensure
definition: Result = upper - lower + 1
Original:
lower: INTEGER
-- Minimum index
Preferred:
No Change
Original:
upper: INTEGER
-- Maximum index
Preferred:
No Change
feature -- Comparison
Original:
is_equal (other: like Current): BOOLEAN
-- Is array made of the same items as other?
-- (Redefined from GENERAL.)
Preferred:
is_equal (other: like Current): BOOLEAN
-- Is array made of the same items as other?
-- (Redefined from GENERAL.)
require else -- from GENERAL
other_not_void: other /= Void
ensure
definition: Result = (lower = other.lower) and (upper = other.upper) --and for_all i, lower..upper (item( i ) = other.item( i ))
ensure then -- from GENERAL
consistent: standard_is_equal (other) implies Result;
same_type: Result implies same_type (other);
symmetric: Result implies other.is_equal (Current)
feature -- Status report
Original:
valid_index (i: INTEGER): BOOLEAN
-- Is i within the bounds of the array?
Preferred:
valid_index (i: INTEGER): BOOLEAN
-- Is i within the bounds of the array?
ensure
-- Defined here as Result = (lower <= i) and (i <= upper)
-- May be redefined in descendants.
Note: There was some disagreement among the implementers as to whether this
feature should remain very fleibly redefinable or not. The comment above is
the compromise that resulted.
feature -- Element change
Original:
enter (v: G; i: INTEGER)
-- Replace i-th entry, if in index interval, by v.
-- (Redefinable synonym for put.)
require
good_key: valid_index (i)
ensure
inserted: item (i) = v
Preferred:
enter (v: like item; i: INTEGER)
-- Replace i-th entry, if in index interval, by v.
-- (Redefinable synonym for put.)
require
valid_index: valid_index( i )
ensure
stable_lower: lower = old lower
stable_upper: upper = old upper
new_item: item(i) = v
stable_before_i: -- for_all n, lower..(i-1) (item(n) = old item(n))
stable_after_i: -- for_all n, (i+1)..upper (item(n) = old item(n))
Original:
force (v: like item; i: INTEGER)
-- Assign item v to i-th entry.
-- Always applicable: resize the array if i falls out of
-- currently defined bounds; preserve existing items.
ensure
inserted: item (i) = v;
higher_count: count >= old count
Preferred:
force (v: like item; i: INTEGER)
-- Assign item v to i-th entry.
-- Always applicable: resize the array if i falls out of
-- currently defined bounds; preserve existing items.
ensure
new_item: item (i) = v;
new_lower: lower = i.min( old lower )
new_upper: upper = i.max( old upper )
new_low_items: -- for_all n, (i+1)..(old lower-1) (item(n) = Void or else item(n) = item(n).default)
new_high_items: -- for_all n, (old upper+1)..(i-1) (item(n) = Void or else item(n) = item(n).default)
in_between: -- for_all n, old lower..old upper (i = n or else item(n) = old item(n))
Original:
frozen put (v: like item; i: INTEGER)
-- Replace i-th entry, if in index interval, by v.
require
good_key: valid_index (i)
ensure
inserted: item (i) = v
Preferred:
frozen put (v: like item; i: INTEGER)
-- Replace i-th entry, if in index interval, by v.
require
valid_index: valid_index( i )
ensure
stable_lower: lower = old lower
stable_upper: upper = old upper
new_item: item(i) = v
stable_before_i: -- for_all n, lower..(i-1) (item(n) = old item(n))
stable_after_i: -- for_all n, (i+1)..upper (item(n) = old item(n))
feature -- Resizing
Original:
resize (minindex, maxindex: INTEGER)
-- Rearrange array so that it can accommodate
-- indices down to minindex and up to maxindex.
-- Do not lose any previously entered item.
require
valid_indices: minindex <= maxindex
ensure
no_low_lost: lower = minindex.min (old lower);
no_high_lost: upper = maxindex.max (old upper)
Preferred: Two different features. One of these, 'accommodate', never shrinks
the array. The array stretches if necessary to accommodate the new bounds,
never losing any items. The other, 'size', changes the bounds of the array
according to its parameters and some items may be lost. The word 'size' should
be treated as a verb here (see below).
The motivation for this change is that the implementers had interpreted the
above comment on 'resize' in these two different ways.
accommodate (min_index, max_index: INTEGER)
-- Rearrange array so that it can accommodate
-- indices down to min_index and up to max_index.
-- Do not lose any previously entered item.
ensure
new_lower: lower = min_index.min(old lower)
new_upper: upper = max_index.max(old upper)
stable_items: -- for_all i, (old lower)..(old upper) (item(i) = old item(i))
new_low_items: -- for_all i, lower..(old lower - 1) (item(i) = Void or else item(i) = item(i).default)
new_high_items: -- for_all i, (old upper + 1)..upper (item(i) = Void or else item(i) = item(i).default)
size(min_index, max_index: INTEGER)
-- Resize the array to the given indices. Do not lose
-- any item that is in the intersection of the closed
-- intervals [lower, upper] and [min_index, max_index].
require
valid_indices: min_index <= max_index + 1
ensure
new_lower: lower = min_index
new_upper: upper = max_index
stable_items: -- for_all i, lower..upper
((old lower <= i and i <= old upper) implies item( i ) = old item( i ))
new_items: -- for_all i, lower..upper
(i < old lower or i > old_upper) implies
(item( i ) = Void or else item( i ) = item(i).default))
Note 1: When 'size' is used as a verb it means "to make a particular size; to
bring to a proper or suitable size."
Note 2: If we only renamed one of these the
other implementers' customers would be driven to distraction.
Note 3: Once a rigorous specification for 'resize' became available it was
immediately clear that different implementers had been interpreting it
differently. In addition, it was easy to accommodate (so to speak)
both versions. Similar benefits were obtained in homing in on the definition
of 'make' in discussions with Roger Browne. I feel good!
feature -- Conversion
to_c: POINTER
-- Address of actual sequence of values,
-- for passing to external (non-Eiffel) routines.
CONCERN: ISE would like the type of this feature be ANY. Again,
the current proposal takes no stand on this issue.
feature -- Duplication
Original:
copy (other: like Current)
-- Reinitialize by copying all the items of other.
-- (This is also used by clone.)
-- (From GENERAL.)
Preferred:
copy (other: like Current)
-- Reinitialize by copying all the items of other.
-- (This is also used by clone.)
-- (From GENERAL.)
require else --from GENERAL
other_not_void: other /= Void
ensure then -- from GENERAL
is_equal: is_equal (other)
invariant
Original:
consistent_size: count = upper - lower + 1;
non_negative_count: count >= 0
Preferred:
consistent_size: count = upper - lower + 1;
nonnegative_count: count >= 0
valid_bounds: lower <= upper + 1
item_equals_at: -- for_all i, lower..upper (item( i ) = Current @ i)
end
----------
X-Sun-Data-Type: default
X-Sun-Data-Name: array.library
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 239
Recommended version of ARRAY. 12/8/95
Note: The only major changes between this version and what I believe was
generally intended in ELKS vintage95 is a new version of the 'make'
routine and the splitting of 'resize' into two features. Otherwise,
all I'm proposing here is a rigorous specification of the features in
(I hope) a readable and forthright way.
Special note: The return type of the query "to_c" is causing some controversy
among the implementers that may take some time to thrash out. This proposal
takes no stand on what that return type should be. The version listed here is
that of ELKS95.
Class ARRAY
indexing
description: "Sequences of values, all of the same type or of a conforming
one, accessible through integer indices in a contiguous interval"
class interface
ARRAY [G]
-- Basic specification set: lower, upper, item
-- Auxiliary specification set: is_equal, valid_index
creation
make (min_index, max_index: INTEGER)
-- Allocate array; set index interval to
-- min_index .. max_index; set all values to default.
require
valid_indices: min_index <= max_index + 1
ensure
lower_initialized : lower = min_index
upper_initialized: upper = max_index
items_initialized: -- for_all i, lower..upper (item(i) = Void or else item(i) = item(i).default)
make_from_array (a: ARRAY [G])
-- Initialize from the values of 'a'.
-- Useful in particular when 'a' is a manifest array.
-- Note: representation may be shared; to avoid sharing,
-- use as "make_from_array(clone( a ))"
require
a_not_void: a /= Void
ensure
lower_initialized : lower = a.lower
upper_initialized: upper = a.upper
items_initialized: -- for_all i, lower..upper (item(i) = a.item(i))
feature -- Initialization
make (min_index, max_index: INTEGER)
-- Allocate array; set index interval to
-- min_index .. max_index; set all values to default.
require
valid_indices: min_index <= max_index + 1
ensure
lower_initialized : lower = min_index
upper_initialized: upper = max_index
items_initialized: -- for_all i, lower..upper (item(i) = Void or else item(i) = item(i).default)
make_from_array (a: ARRAY [G])
-- Initialize from the values of 'a'.
-- Useful in particular when 'a' is a manifest array.
-- Note: representation may be shared; to avoid sharing,
-- use as "make_from_array(clone( a ))"
require
a_not_void: a /= Void
ensure
lower_initialized : lower = a.lower
upper_initialized: upper = a.upper
items_initialized: -- for_all i, lower..upper (item(i) = a.item(i))
feature -- Access
entry (i: INTEGER): G
-- Entry at index i.
-- (Redefinable synonym for item and infix "@".)
require
valid_index: valid_index( i )
frozen item (i: INTEGER): G
-- Entry at index i.
require
valid_index: valid_index( i )
frozen infix "@" (i: INTEGER): G
-- Entry at index i.
require
valid_index: valid_index( i )
ensure
definition: Result = item( i )
feature -- Measurement
count: INTEGER
-- Number of available indices
ensure
definition: Result = upper - lower + 1
lower: INTEGER
-- Minimum index
upper: INTEGER
-- Maximum index
feature -- Comparison
is_equal (other: like Current): BOOLEAN
-- Is array made of the same items as other?
-- (Redefined from GENERAL.)
require else -- from GENERAL
other_not_void: other /= Void
ensure
definition: Result = (lower = other.lower) and (upper = other.upper) --and for_all i, lower..upper (item( i ) = other.item( i ))
ensure then -- from GENERAL
consistent: standard_is_equal (other) implies Result;
same_type: Result implies same_type (other);
symmetric: Result implies other.is_equal (Current)
feature -- Status report
valid_index (i: INTEGER): BOOLEAN
-- Is i within the bounds of the array?
ensure
-- Defined here as Result = (lower <= i) and (i <= upper)
-- May be redefined in descendants.
feature -- Element change
enter (v: like item; i: INTEGER)
-- Replace i-th entry, if in index interval, by v.
-- (Redefinable synonym for put.)
require
valid_index: valid_index( i )
ensure
stable_lower: lower = old lower
stable_upper: upper = old upper
new_item: item(i) = v
stable_before_i: -- for_all n, lower..(i-1) (item(n) = old item(n))
stable_after_i: -- for_all n, (i+1)..upper (item(n) = old item(n))
force (v: like item; i: INTEGER)
-- Assign item v to i-th entry.
-- Always applicable: resize the array if i falls out of
-- currently defined bounds; preserve existing items.
ensure
new_item: item (i) = v;
new_lower: lower = i.min( old lower )
new_upper: upper = i.max( old upper )
new_low_items: -- for_all n, (i+1)..(old lower-1) (item(n) = Void or else item(n) = item(n).default)
new_high_items: -- for_all n, (old upper+1)..(i-1) (item(n) = Void or else item(n) = item(n).default)
in_between: -- for_all n, old lower..old upper (i = n or else item(n) = old item(n))
frozen put (v: like item; i: INTEGER)
-- Replace i-th entry, if in index interval, by v.
require
valid_index: valid_index( i )
ensure
stable_lower: lower = old lower
stable_upper: upper = old upper
new_item: item(i) = v
stable_before_i: -- for_all n, lower..(i-1) (item(n) = old item(n))
stable_after_i: -- for_all n, (i+1)..upper (item(n) = old item(n))
feature -- Resizing
accommodate (min_index, max_index: INTEGER)
-- Resize array so that it can accommodate
-- indices down to min_index and up to max_index.
-- Do not lose any previously entered item.
ensure
new_lower: lower = min_index.min(old lower)
new_upper: upper = max_index.max(old upper)
stable_items: -- for_all i, (old lower)..(old upper) (item(i) = old item(i))
new_low_items: -- for_all i, lower..(old lower - 1) (item(i) = Void or else item(i) = item(i).default)
new_high_items: -- for_all i, (old upper + 1)..upper (item(i) = Void or else item(i) = item(i).default)
size(min_index, max_index: INTEGER)
-- Resize the array to the given indices. Do not lose
-- any item that is in the intersection of the closed
-- intervals [lower, upper] and [min_index, max_index].
require
valid_indices: min_index <= max_index
ensure
new_lower: lower = min_index
new_upper: upper = max_index
stable_items: -- for_all i, lower..upper
((old lower <= i and i <= old upper) implies item( i ) = old item( i ))
new_items: -- for_all i, lower..upper
(i < old lower or i > old_upper) implies
(item( i ) = Void or else item( i ) = item(i).default))
feature -- Conversion
to_c: POINTER
-- Address of actual sequence of values,
-- for passing to external (non-Eiffel) routines.
CONCERN: ISE would like the type of this feature be ANY. Again,
the current proposal takes no stand on this issue.
feature -- Duplication
copy (other: like Current)
-- Reinitialize by copying all the items of other.
-- (This is also used by clone.)
-- (From GENERAL.)
require else --from GENERAL
other_not_void: other /= Void
ensure then -- from GENERAL
is_equal: is_equal (other)
invariant
consistent_size: count = upper - lower + 1;
nonnegative_count: count >= 0
valid_bounds: lower <= upper + 1
item_equals_at: -- for_all i, lower..upper (item( i ) = Current @ i)
end

|
|