From: Rony G. F. <Ron...@wu...> - 2007-04-21 13:10:13
|
Rick McGuire wrote: > I call your attention to line 298 of file > kernel/RexxClasses/StreamClasses.orx. Interestingly, line # 298 corrsponds to line # 353 in the 3.1.2 release branch! (Or with other words: applying use strict saved 65 lines or calculated from 353 this is a reduction of 1/6). > Supplier is most definitely NOT the only implementation of a supplier > class in ooRexx, and has not been since the day IBM turned the code > over to RexxLA. Oversaw that one! > This supplier implementation is exactly the sort of lazy supplier I > described and it exactly the sort that cannot implement an ITEMS method. No, there is *no* problem whatsoever adding "items" to the .Supplier class as the "StreamSupplier" class does *not* specializie .Stream! > No further arguments based on "we've never used that capability" can > be accepted in this discussion. :) Seriously, there are obvious two different concepts that are mixed up here: * the concept of specializing classes with inheriting (implementation) behaviour, * the independent concept of interfaces (set of methods that together specifay a specific, typical, identifiable behaviour) with defining a set of methods that must be implemented in order to announce that a class adheres to it. The defintion and implementations of ".Supplier" and ".StreamSupplier" are *totally* independent of each other (therefore the class ".StreamSupplier" is not affected by any changes to ".Supplier"). What both have in common though is a set of methods that together realize a "SupplierIterator" interface: AVAILABLE, INDEX, ITEM, NEXT, which are used together to carry out the "supplying iteration". But this commonality is not explicitly expressed or defined (and it would be hard, if not impossible to express in 3.1.x or earlier). The current (3.1.x) implementation would still allow to check with .Object's HASMETHOD for the presence of these four methods, and if they are there assume, that we can interact with such a class as if it represents a SupplierIterator; but we could be mistaken, as these methods could be there by incidence. Starting with 3.2 (in the present form) we *are* able to express this excplicitly, e.g. ::class "Iterator" mixinclass object -- define an Iterator class ::class "SupplierIterator" mixinclass Iteraor -- defin a SupplierIterator ::method available abstract -- must have a method "available" implemented ::method index abstract -- must have a method "index" implemented ::method item abstract -- must have a method "item" implemented ::method next abstract -- must have a method "next" implemented -- ... then for .Supplier the class directive needs to be changed to ::class "Supplier" subclass Object inherit SupplierIterator -- explicitly declare we are also a SupplierIterator ... -- then for the .StreamSupplier directive ::class "StreamSupplier" subclass Object inherit SupplierIterator This would make sure that any implementation of a SupplierIterator adheres to the SupplierIterator "protocol" (implementing its abstract methods) and at runtime one can determine whether it is possible to treat the object as a SupplierIterator (e.g. in the context of a hypothetical "DO...SUPPLIER..." statement, just testing whether o~isA(.SupplierIterator) yields .true or not). Actually, thinking about this, I am inclined to file this as a RFE! --- Adding additional methods to .Supplier would not affect the SupplierIterator definitoins at all and would not force any implementation of SupplierIterator to also add those methods (like "items", "allIndexes", "allItems" which would make sense for the .Supplier class). ---rony P.S.: An alternative would be to introduce explicitly interfaces. In that case I would suggest: * an INTERFACE directive o should be treated as classes for which by default MIXINCLASS is assumed (i.e. all interfaces can be mixed and combined as one sees it fit) * any number of method directives with the optional attributes "CLASS", "ATTRIBUTE": all interface methods must be abstract (if default implementations are possible and meant to be reusable via inheritance by classes, then one must define it then as a class, in order to be able to inherit the implementation of methods) * any class implementing one or more interfaces then needs a new keyword option on the class directive, like "implements"; probably in the parenthesis form, i.e. the above example: ::interface "Iterator" ::interface "SupplierIterator" mixinclass Iterator -- subclass/mixinclass would be synonyms for interfaces ::method available ::method index ::method item ::method next ... ::class 'Supplier' implements (SupplierIterator) ... ::class 'StreamSupplier' implements (SupplierIterator) Introducing the concept of interfaces would make it easier to map and match them with the interface concept in other languages/systems like Java or .Net. |