NICE-ESG-Libs Digest Thu, 25 May 95 Volume 1 : Issue 227
Today's Topics:
Array recommendations, from Jim McKim
Jason explains yesterday's odd message
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: Thu, 25 May 95 23:32:20 BST
From: Simon Parker <sparker@eiffel.ie>
Subject: Array recommendations, from Jim McKim
To: NICE Libraries Committee <NICE-ESG-Libs@atlanta.twr.com>
--VERSION:801442377:455017068:445055017:-1375681016
Content-Type: TEXT/PLAIN; charset=US-ASCII
Delegates,
Jim McKim sent this thoughtful piece of work to me, with a request that I pass it on to
the Library committee.
Although Christine is paying close attention to Library committee matters, her
temporary electronic mail facilities in Europe would make the task of relaying messages
arduous.
I have posted this message on her behalf, boldly assuming her approval and yours. If
this breach of rules and etiquette is unjustified, please forgive me. In any case, it will
not become a habit.
Regards,
Simon
- - - - - - - - - -
Simon Parker
Eiffel Ireland (Consultancy, training, compilers, books)
45 Hazelwood, Shankill, Co Dublin, Ireland
(+353 1) 282 3487 sparker@eiffel.ie http://www.eiffel.ie/Eiffel/
------------------------------ Begin quote ------------------------------------------
To the Library Committee.
Accompanying this document please find proposed changes to the flat-short
form of the ARRAY class. As I am not a member of the Committee, this is
not a formal proposal. I hope that one or more of you will see sufficient
merit in this work that you will sponsor the proposal yourselves.
Motivation: ARRAY and STRING are among the first classes that people learning
Eiffel will see. As such it is especially important that these classes are
well documented and well specified via preconditions, postconditions, and
assertions. Right now the following scenario is all too typical:
1) I espouse the marvelous benefits of programming by contract as
a tool for documenting class libraries so that readers can understand
classes _without_ reading the code.
2) Students look at the short form of ARRAY, specifically at "make" and
ask, "Where are my min_index and max_index parameters saved?"
3) I answer, "In lower and upper."
4) They retort, "How do you know?"
5) I reply sheepishly, "I looked at the code."
As many of you know I've been interested in and writing about
Programming by Contract for some time and have developed some criteria
for applying it well. The result of applying these criteria to the
ARRAY class is what you have before you. In all but one or two cases
I have not recommended any changes that would affect the implementation
of a feature. I've just tried to give clear and complete pre and postconditions
that specify the _current_ behavior.
There are actually three files that accompany this document. These are
1) The original version, array.original, taken from the ASCII directory
at ISE's ftp site on May 24. The ONLY difference between what you have here
and what was at ISE on that date is that I've reformatted the former for
easier reading.
2) The recommended diff's version, array.recs. This version shows the
original short form for each feature, then my preferred form and then
some justifications for the recommended changes.
3) The "final" version, array.done. This version just includes my
preferred spec's for each feature i.e no original versions, no
justifications.
Assumption: I have assumed that comments within assertion clauses show up
in the short form. Not all vendors support this at the moment, although
I don't believe any are averse to providing such support in the future.
A little bit on the criteria I used:
1) Pick a small set of queries to use as a "specification set". For ARRAY,
the specification set consists of lower, upper, and item. Each command
specifies precisely how it affects the value of each of these queries,
whether it changes those values or not.
2) Each query not in the specification set is specified in terms of
values in that set.
3) You will see comments of the form for_all i, min..max (some_assertion).
This structure asserts that "some_assertion" is true for each integer i
from min up to max. If min > max then the overall assertion is true.
4) Blatant Plug: To find out more about these criteria, come to my
Tutorial at either TOOLS USA or OOPSLA :-).
I hope you will take some time to look these suggested changes over and
that you will accept them by acclamation :-).
Please contact me with any questions or concerns.
Best regards,
-- Jim McKim
-----------------------------------End quote -------------------------------------
(Attachments in another message, or below)
--VERSION:801442377:455017068:445055017:-1375681016
Content-Type: TEXT/PLAIN; SizeOnDisk=27723; name="JCMARRAY.TXT"; CHARSET=US-ASCII
Content-Description: Three files from Jim McKim
----------
X-Sun-Data-Type: default
X-Sun-Data-Name: array.original
X-Sun-Content-Lines: 146
Original version -- array.original
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]
creation
make (minindex, maxindex: INTEGER)
-- Allocate array; set index interval to
-- minindex .. maxindex; set all values to default.
-- (Make array empty if minindex > maxindex.)
ensure
no_count: (minindex > maxindex) implies (count = 0);
count_constraint: (minindex <= maxindex) implies (count = maxindex - minindex + 1)
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.)
feature -- Initialization
make (minindex, maxindex: INTEGER)
-- Set index interval to minindex .. maxindex;
-- reallocate if necessary; set all values to default.
-- (Make array empty if minindex > maxindex.)
ensure
no_count: (minindex > maxindex) implies (count = 0);
count_constraint: (minindex <= maxindex) implies (count = maxindex - minindex + 1)
make_from_array (a: ARRAY [G])
-- Initialize from the items of a; reallocate if
-- necessary. (Useful in proper descendants of
-- class ARRAY, to initialize an array-like object
-- from a manifest array.)
feature -- Access
entry (i: INTEGER): G
-- Entry at index i, if in index interval
-- (Redefinable synonym for item and infix "@".)
require
good_key: valid_index (i)
frozen item (i: INTEGER): G
-- Entry at index i, if in index interval
require
good_key: valid_index (i)
frozen infix "@" (i: INTEGER): G
-- Entry at index i, if in index interval
require
good_key: valid_index (i)
feature -- Measurement
count: INTEGER
-- Number of available indices
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.)
feature -- Status report
valid_index (i: INTEGER): BOOLEAN
-- Is i within the bounds of the array?
feature -- Element change
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
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
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
feature -- Resizing
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
good_indices: minindex <= maxindex
ensure
no_low_lost: lower = minindexlmin (old lower);
no_high_lost: upper = maxindexlmax (old upper)
feature -- Conversion
to_c: POINTER
-- Address of actual sequence of values,
-- for passing to external (non-Eiffel) routines.
feature -- Duplication
copy (other: like Current)
-- Reinitialize by copying all the items of other.
-- (This is also used by clone.)
-- (From GENERAL.)
invariant
consistent_size: count = upper - lower + 1;
non_negative_count: count >= 0
end
----------
X-Sun-Data-Type: default
X-Sun-Data-Name: array.recs
X-Sun-Content-Lines: 521
Recommended changes with justifications. -- array.recs
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]
Preferred:
Add comment that gives the set of features used for specifying the class.
-- Specification set: lower, upper, item
creation
Original:
make (minindex, maxindex: INTEGER)
-- Allocate array; set index interval to
-- minindex .. maxindex; set all values to default.
-- (Make array empty if minindex > maxindex.)
ensure
no_count: (minindex > maxindex) implies (count = 0);
count_constraint: (minindex <= maxindex) implies (count = maxindex - minindex + 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
ensure
lower_initialized : lower = min_index
upper_initialized: upper = max_index
items_initialized: -- for_all i, lower..upper (item(i) /= Void implies item(i) = item(i).default)
Justification and Notes:
1) Enforce usual notation conventions i.e. min_index instead of minindex.
2) Why no precondition in the original version? Are we really doing users
a favor by letting them call make( 7, -10 ) and giving them an array with
lower = 0 and upper = -1? This change could break some code, but it's almost
certainly code that shouldn't exist anyway. (He said arrogantly :-)).
3) The old postcondition tells us about count. IMHO, lower, upper, and
item are more important. count can be handled in terms of these.
Special Note: Hers's a compromise version if we can't change the precondition.
make (minindex, maxindex: INTEGER)
-- Allocate array; set index interval to
-- minindex .. maxindex; set all values to default.
-- (Make array empty if minindex > maxindex.)
ensure
no_items: min_index > max_index implies (lower = 0 and upper = -1)
lower_initialized : min_index <= max_index implies lower = min_index
upper_initialized: min_index <= max_index implies upper = max_index
items_initialized: -- for_all i, lower..upper (item(i) /= Void implies item(i) = item(i).default)
Justification and Notes:
1) If we're gonna let 'em send a bad min_index, max_index combination, let's
at least tell 'em what really happens.
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 items of a.
-- (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))
Justification and Notes:
1) Include precondition for safety, clarity, simplicity.
2) Have the postconditions say what happens.
feature -- Initialization
Special Note: I assume these two features are repeated here as they are
both public and creation features. Naturally my recommendations and reasoning
are the same as above. I haven't repeated the Justifications.
Original:
make (minindex, maxindex: INTEGER)
-- Set index interval to minindex .. maxindex;
-- reallocate if necessary; set all values to default.
-- (Make array empty if minindex > maxindex.)
ensure
no_count: (minindex > maxindex) implies (count = 0);
count_constraint: (minindex <= maxindex) implies (count = maxindex - minindex + 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
ensure
lower_initialized : lower = min_index
upper_initialized: upper = max_index
items_initialized: -- for_all i, lower..upper (item(i) /= Void implies 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 items of a.
-- (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, if in index interval
-- (Redefinable synonym for item and infix "@".)
require
large_enough: i >= lower
small_enough: i <= upper
ensure
Result = item( i )
Justification and Notes:
1) By using upper and lower here we can keep the specification set small.
2) Also valid_index is not well specified so is not a sufficient precondition
3) Will descendants want a different postcondition? (!) If we want to allow
that possibility then we should omit this one or make it a comment.
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, if in index interval
require
large_enough: i >= lower
small_enough: i <= upper
Justification and Notes:
1) By using upper and lower here we can keep the specification set small.
2) Also valid_index is not well specified so is not a sufficient precondition
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, if in index interval
require
large_enough: i >= lower
small_enough: i <= upper
ensure
Result = item( i )
Justification and Notes:
1) By using upper and lower here we can keep the specification set small.
2) Also valid_index is not well specified so is not a sufficient precondition.
3) Need postcondition to map this feature to specification set.
feature -- Measurement
Original:
count: INTEGER
-- Number of available indices
Preferred:
count: INTEGER
-- Number of available indices
ensure
Result = upper - lower + 1
Justification and Notes:
1) Need to say what the Result is.
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
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)
Justification and Notes:
1) I think the missing precondition in the original is an error as it's
in GENERAL.
2) The postcondition just tells it like it is - I hope.
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
Result = (lower <= i) and (i <= upper)
Justification and Notes:
1) Just tell 'em the precise truth.
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: G; i: INTEGER)
-- Replace i-th entry, if in index interval, by v.
-- (Redefinable synonym for put.)
require
index_large_enough: i >= lower
index_small_enough: i <= upper
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))
Justification and Notes:
1) Same notes on replacing valid_index as before.
2) If you haven't seen this flavor of postcondition before, it looks a lot
heavier than it is. While
this is clearly correct for put, I suppose it may be too much here,
depending on how much leeway we're willing to allow descendants.
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;
stable_before_i: i <= old upper implies for_all n, (old lower)..(i-1) (item(n) = old item(n))
stable_after_i: i >= old lower implies for_all n, (i+1)..(old upper) (item(n) = old item(n))
new_lower: i < old lower implies lower = i
new_low_items -- i < old lower implies for_all n, (lower+1)..(old lower-1) (item(n) /= Void implies item(n) = item(n).default)
new_upper: i > old upper implies upper = i
new_high_items -- i > old upper implies for_all n, (old upper)..(upper-1) (item(n) /= Void implies item(n) = item(n).default)
Justification and Notes:
1) This looks complex 'cause it is :-) It's basically what happens when
the supplier takes on the entire contract.
Special Note: If I had my druthers I'd lose this feature. If clients want
to expand the ARRAY, let 'em call resize first. But maybe that's just
the control freak in me coming out.... I've kept this feature in the
"finished" version.
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
index_large_enough: i >= lower
index_small_enough: i <= upper
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))
Justification and Notes:
1) Usual comments on replacing valid_index in the precondition.
2) The postcondition just speaks the truth.
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:
resize (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.
require
valid_min_index: min_index <= lower
valid_max_index: max_index >= upper
ensure
new_lower: lower = min_index
new_upper: upper = max_index
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 implies item(i) = item(i).default)
new_high_items: -- for_all i, (old upper + 1)..upper) (item(i) /= Void implies item(i) = item(i).default)
Justification and Notes:
1) While it's not entirely clear from the original short, it's clear from
both Tower's and ISE's code that the array is not allowed to shrink from
either end. The new precondition just makes that explicit.
2) And the new postcondition just makes it real clear what happens.
feature -- Conversion
Original:
to_c: POINTER
-- Address of actual sequence of values,
-- for passing to external (non-Eiffel) routines.
Preferred:
No Change. Anyone who wants to mess around with C pretty much has to
expect to look at the code.
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
new_lower: lower = other.lower
new_upper: upper = other.upper
new_items: -- for_all i, lower..upper (item(i) = other.item(i)
ensure then -- from GENERAL
is_equal: is_equal (other)
Justification and Notes:
1) Again I believe the absence of the precondition in the original is an
error.
2) Again the postcondition just says what really happens. The old
postcondition from GENERAL really does the job, but I do like specifying
directly in terms of the specification set.
Original:
invariant
consistent_size: count = upper - lower + 1;
non_negative_count: count >= 0
Preferred:
invariant
consistent_size: count = upper - lower + 1;
positive_count: count >= 1
valid_bounds: upper >= lower
valid_indices: -- for_all i:INTEGER (valid_index(i) = (lower <= i and i <= upper)
item_equals_at: -- for_all i, lower..upper (item( i ) = Current @ i)
item_equals_entry: -- for_all i, lower..upper (item( i ) = entry(i))
Justification and Notes:
1) Stronger assertions assume the preferred versions of make and
make_from_array are adopted.
2) Also have assumed entry's we do not want descendants to change the Result
of the call.
end
----------
X-Sun-Data-Type: default
X-Sun-Data-Name: array.done
X-Sun-Content-Lines: 219
Preferred version of ARRAY. -- array.done
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]
-- Specification set: lower, upper, item
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
ensure
lower_initialized : lower = min_index
upper_initialized: upper = max_index
items_initialized: -- for_all i, lower..upper (item(i) /= Void implies item(i) = item(i).default)
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.)
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
ensure
lower_initialized : lower = min_index
upper_initialized: upper = max_index
items_initialized: -- for_all i, lower..upper (item(i) /= Void implies item(i) = item(i).default)
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.)
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, if in index interval
-- (Redefinable synonym for item and infix "@".)
require
large_enough: i >= lower
small_enough: i <= upper
ensure
Result = item( i )
frozen item (i: INTEGER): G
-- Entry at index i, if in index interval
require
large_enough: i >= lower
small_enough: i <= upper
frozen infix "@" (i: INTEGER): G
-- Entry at index i, if in index interval
require
large_enough: i >= lower
small_enough: i <= upper
ensure
Result = item( i )
feature -- Measurement
count: INTEGER
-- Number of available indices
ensure
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
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
Result = (lower <= i) and (i <= upper)
feature -- Element change
enter (v: G; i: INTEGER)
-- Replace i-th entry, if in index interval, by v.
-- (Redefinable synonym for put.)
require
index_large_enough: i >= lower
index_small_enough: i <= upper
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;
stable_before_i: i <= old upper implies for_all n, (old lower)..(i-1) (item(n) = old item(n))
stable_after_i: i >= old lower implies for_all n, (i+1)..(old upper) (item(n) = old item(n))
new_lower: i < old lower implies lower = i
new_low_items -- i < old lower implies for_all n, (lower+1)..(old lower-1) (item(n) /= Void implies item(n) = item(n).default)
new_upper: i > old upper implies upper = i
new_high_items -- i > old upper implies for_all n, (old upper)..(upper-1) (item(n) /= Void implies item(n) = item(n).default)
frozen put (v: like item; i: INTEGER)
-- Replace i-th entry, if in index interval, by v.
require
index_large_enough: i >= lower
index_small_enough: i <= upper
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
resize (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.
require
valid_min_index: min_index <= lower
valid_max_index: max_index >= upper
ensure
new_lower: lower = min_index
new_upper: upper = max_index
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 implies item(i) = item(i).default)
new_high_items: -- for_all i, (old upper + 1)..upper) (item(i) /= Void implies item(i) = item(i).default)
feature -- Conversion
to_c: POINTER
-- Address of actual sequence of values,
-- for passing to external (non-Eiffel) routines.
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
new_lower: lower = other.lower
new_upper: upper = other.upper
new_items: -- for_all i, lower..upper (item(i) = other.item(i)
ensure then -- from GENERAL
is_equal: is_equal (other)
invariant
consistent_size: count = upper - lower + 1;
positive_count: count >= 1
valid_bounds: upper >= lower
valid_indices: -- for_all i:INTEGER (valid_index(i) = (lower <= i and i <= upper)
item_equals_at: -- for_all i, lower..upper (item( i ) = Current @ i)
item_equals_entry: -- for_all i, lower..upper (item( i ) = entry(i))
end
--VERSION:801442377:455017068:445055017:-1375681016--
Date: Thu, 25 May 95 15:15:25 -0400
From: Jason Schroeder <shrode@wsc.com>
Subject: Jason explains yesterday's odd message
To: NICE-ESG-Libs@atlanta.twr.com
Dear Library Committee,
A letter of mine accidentally went to the committee mailing list
instead of its intended recipient. I was responding to a lobbyist
for Mr. Johnson as chair. I did not intend to share my abruptness
with the committee.
I carry no disrespect for the committee or the chair and apologise
for any distress I might have caused my fellow members and the
Eiffel community at large. I intend to be an active and
trustworthy member - I like Eiffel, otherwise I would not be here.
I wish my initial act with the committee would have been a formal
introduction of myself and my views rather than writing this letter.
That will be coming soon.
As usual, there are reasons to vote and not vote for both
candidates. If somebody wishes to discuss these options with me, I
will reply - and I will not use the wrong keystrokes in Emacs to
reply ;-)
Jason Schroeder

|
|