NICE-ESG-Libs Digest        Thu, 22 Feb 96       Volume 2 : Issue  16 

Today's Topics:
                         strip and ARRAY[ANY]


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, 22 Feb 96 13:20:19 EST From: tynor (Steve Tynor) Subject: strip and ARRAY[ANY] To: nice-esg-libs, eiffel@swissoft.h.provi.de (Michael Schweitzer) Submitted for discussion. Suppose I have the following class: class A feature s : STRING; x, y : INTEGER; foo is -- This feature is not supposed to change anything but `x' do ... ensure -- all the fields of Current except `x' should be unchanged: equal (strip(x), old strip(x)); end end The postcondition can never succeed, even if Current is completely unchanged! (yet this is the canonical way that strip is used in the examples of ETL). Why, you ask? Because strip creates an ARRAY[ANY] (ETL pg. 397). Therefore instead of putting `y' into an array, `y's reference equivalent (an INTEGER_REF) is put in the array. So, the array contains a reference to a STRING and a reference to an INTEGER_REF. But the "old strip" contains a different INTEGER_REF (one created by evaluating Current before executing the body of the routine). Since `equal' is defined in terms if `is_equal', it's the equivalent of saying: strip(x).is_equal (old strip(x)) But ARRAY's `is_equal' is defined (and correctly so, in my opinion) to simply check whether "for all i, item(i) = other.item(i)". That's _reference_equality_ for ARRAY[ANY]. So, the two strip expressions will never be equal. [Side note: as far as I'm aware, all existing implementations implement ARRAY:is_equal in this manner, and it's in fact spelled out to have these semantics in Jim McKim's recent touch-up of the ARRAY class. I don't expect any argument that this is the correct semantics for the feature (but you may suprise me...)]. The only solution that makes sense is to add a new feature to ARRAY which checks `is_equal' on each element instead of using `='. That is, items_are_equal (other : like Current) -- Is each item in Current `is_equal' to the corresponding -- item in `other'? require other_not_void: other /= Void; ensure -- for all i, -- ((item(i) = Void or other.item(i) = Void) -- implies (item(i) = Void and other.item(i) = Void)) -- or else item(i).is_equal(other.item(i)) Then we can rewrite the example postcondition as: ... ensure strip(x).items_are_equal(old strip(x)) end and it "does the right thing". If you agree, then I will write up a proposal for adding a new `items_are_equal' standard feature to ARRAY. (Off the top of my head, I can think of several alternative names: `items_are_equal', `elements_are_equal', `is_equal_items', `is_equal_elements', `equal_items' `same_items'. I prefer `items_are_equal' or `equal_items' since they are the most naturally English phrases. `same_items' is not descriptive enough since it's not clear from the name that `same_items' is any different than `is_equal'. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Llamas are larger than frogs. Steve Tynor Internet: Steve.Tynor@atlanta.twr.com Tower Technology WWW: http://www.twr.com/