From: Guus L. jr. <guu...@it...> - 2010-05-11 18:49:43
|
Hello, Today I encountered a situation whereby HASH_TABLE.current_keys caused the runtime to throw a couple a Catcall warnings onto my console. Within the bench, it was quickly discovered that these came from ARRAY.make, which uses ({G}).default to make_filled_area for itself. Below is a patch that will avoid the Catcall warnings (which are disguised attachment errors). Now onto to discussion about `default'. This feature is defined in ANY as `frozen default: detachable like Current'. This feature has an empty body. Although syntactically correct, we have to then wonder what a frozen default would yield when void-safety becomes the standard. A `default' value as such would seem useful in a way for non-object types (INTEGER and friends) and one could possibly think of default values for certain objects. For example a USER_AGENT_STRING could inherit from STRING and have a default value of say "Eiffel Request Client". That is not possible, though, because of the frozen nature of `default'. Since there is only an empty body, a Void object is always created, which sort of defeats the purpose of void-safety (in general terms, that is). I can see two solutions: 1) Remove `default' from ANY, as it is not useful in void-safety environments, except for INTEGER and friends. This can be done only in Eiffel versions after the standard adopts void-safety. 2) Implement the `frozen default' to `create Result'. This, however, does not work for INTEGER and friends, as they cannot be created (since they are not objects). A third scenario comes to mind, which is my patch below. In this scenario, we would leave `default' be, and "work around" its issues, by deeply checking Void-Safety. Although hidden within a couple of classes and feature calls, the compiler should still detect that ARRAY.make uses void-unsafe values in its call-chain. We have the following types: 1) HASH_TABLE [G, K -> detachable HASHABLE] (instantiated as HASH_TABLE [STRING, STRING], which will thus be a HASH_TABLE [attached STRING, detachable STRING]) 2) ARRAY [G] (instantiated as ARRAY [detachable STRING]) 3) SPECIAL [T] (instantiated as SPECIAL [detachable STRING]) We also have the following features: 1) current_keys: ARRAY [K], instantiated as current_keys: ARRAY [detachable STRING] 2) make (min_index, max_index: INTEGER), which calls make_filled_area (({G}).default, max_index - min_index + 1) (called as make_filled_area (({detachable STRING}).default, max_index - min_index + 1)) 3) frozen default: detachable like Current instantiated as frozen default: detachable STRING 4) make_filled (v: T; n: INTEGER) (from SPECIAL [T], called by make_filled_area in TO_SPECIAL [T]) (instantiated as make_filled (v: detachable STRING; n: INTEGER) 5) fill_with (v: T; start_index, end_index: INTEGER) instantiated as fill_with (v: detachable STRING; start_index, end_index: INTEGER) etc. So, the compiler is correct in saying nothing: all types involved are detachable. For the human mind, however SPECIAL [T] means that T is attached. This is thus not always the case: Looking at this, the real culprit seems to be the generic declaration of HASH_TABLE: HASH_TABLE [G, K -> detachable HASHABLE]. Why does K need to be detachable? And if so, must then not all generic suppliers of HASH_TABLE be implemented as though their generic parameter *could* be detachable? This seems to not have taken place. So the only *real* solution to this problem would seem to implement the below or a similar patch for all classes where the generic parameter *could* be detachable, and thus yield a real-time value of Void. Patch against ARRAY.e (Revision 454): Index: array.e =================================================================== --- array.e (revision 454) +++ array.e (working copy) @@ -78,7 +78,11 @@ lower := min_index upper := max_index if min_index <= max_index then - make_filled_area (({G}).default, max_index - min_index + 1) + if attached {G} ({G}).default as l_default_g then + make_filled_area (l_default_g, max_index - min_index + 1) + else + make_empty_area (max_index - min_index + 1) + end else make_empty_area (0) end ***** END OF PATCH ****** Any thoughts on this subject? Regards, Guus |