Re: Inheritance in SmartEiffel
José Bollo <[email protected]>
| Newsgroups | gmane.comp.lang.eiffel.smalleiffel |
|---|---|
| Message-ID | <[email protected]> |
Le jeudi 28 Avril 2005 09:45, vous avez écrit :
> As some discussion is now under way in other current threads about
> possible mechanisms to achieve some specific and therefore limited
> objectives, I would like to return to some questions I posed to language
> theorists about inheritance. As the only previous response was a
> thoughtful discussion of the problem, I wondered if the questions I
> asked demonstrated my lack of understanding, to which I will readily
> agree, or were the questions of themselves not readily answerable?
> In earlier posting,
> -- http://wwsympa.loria.fr/wwsympa/arc/smarteiffel/2005-04/msg00112.html
> -- http://wwsympa.loria.fr/wwsympa/arc/smarteiffel/2005-04/msg00114.html
> I attempted to show a problem with both normal and expanded inheritance
> and posed some questions about their significance. I would like to
> reiterate their main direction.
> Initially only one inheritance mechanism was introduced into Eiffel. As
> this proved to be inadequate, a further expanded form has now been
> introduced. Does anyone know, if there is any theoretical understanding
> of inheritance, which would lead us to believe that these two mechanisms
> are sufficient to cope with all currently foreseeable eventualities and
> requirements.
> It appears to me that a third mechanism would appear to be capable of
> solving the inheritance problem I identified. That would be to specify
> that the inheritance was being restricted in some way. This inheritance
> would be conforming (required for the use of existing libraries) but
> would prevent cat-calls by forbidding access to the wider range of
> features implied by the normal inheritance mechanism.
> Furthermore, would the availability of such a mechanism facilitate the
> sub-ranging of numeric values which appears to be a significant problem
> using existing techniques?
> I would appreciate any contribution, as a resounding silence might
> indicate a major faux pas or the asking of questions which are not
> easily answered.
> I believe that some answer is required as the present mechanism is
> either flawed or is insufficiently understood to make it work, as it
> ought. In either case it demands attention.
> Please comment
> Frank Salter
Hi
there had been no reply to your request for comment into the smarteiffel
mailing list.
However i feel your remarks very interresting.
I was very interrested with your first post and the error that you described:
> class EMPLOYEE
>
> creation {TEST} with_salary
>
> feature {TEST}
>
> with_salary (initial_salary : like salary)
> is
> do
> staff_number_allocator.increment;
> staff_number := staff_number_allocator.value
> salary := initial_salary;
> end
>
> staff_number : INTEGER;
>
> feature {TEST, STAFF_LIST}
>
> salary : REAL;
>
> feature {NONE}
>
> staff_number_allocator : COUNTER is once create Result; end
>
> end
> class STAFF_LIST
> insert LINKED_LIST[EMPLOYEE]
>
> creation make
>
> feature {TEST}
>
> salary_bill : REAL
> is
> local employees : ITERATOR[EMPLOYEE];
> do
> from employees := get_new_iterator;
> until employees.is_off
> loop
> Result := Result + employees.item.salary;
> employees.next;
> end
> end
>
> end
> class TEST
>
> creation program
>
> feature
>
> program
> is
> do
> create staff.make;
> staff.add_last(create {EMPLOYEE}.with_salary(25000));
> staff.add_last(create {EMPLOYEE}.with_salary(22500));
> staff.add_last(create {EMPLOYEE}.with_salary(20000));
> staff.do_all(agent show_employee(?));
>
> std_output.put_real_format(staff.salary_bill, 2);
> std_output.put_new_line;
> end
>
> staff : STAFF_LIST;
>
> show_employee (e : EMPLOYEE)
> is
> do
> std_output.put_integer(e.staff_number);
> std_output.put_new_line;
> end
> end
> ****** Fatal Error: Cannot pass `other' which is of type STAFF_LIST
> into formal type COLLECTION[EMPLOYEE].
> Line 190 column 20 in LINKED_LIST (..../linked_list.e):
> from_collection(other)
> ^
> Line 284 column 26 in LINKED_LIST (.../linked_list.e):
> from_collection (model: COLLECTION[like item]) is
> ^
> ------
> File "test.make" not found. Error(s) during `compile_to_c'.
The remark of Daniel Moisset about the meaning of Current was great.
I think that it is a real good question for thoericians, what i am far to be.
In class linked_list:
class LINKED_LIST feature ...
copy(other: like Current) is do from_collection(other) end
from_collection(model: COLLECTION[like item]) is ...
end
--------------
The feature copy is not called neither directly nor indirectly. So the error
would not prohibit the construction of a valid system.
From SE 2.0, the full classes are checked so the error is detected. With
anterior versions of SE, only the living system was checked and then that
error coulded be not detected (but insert had been an error ;^).
---------------
In the feature copy of LINKED_LIST, the type of 'Current' implies a
conforming to LINKED_LIST. That is the point that causes the error because
when insert is used then STAFF_LIST does not conform to the LINKED_LIST.
I am thinking that maybe the conformant meaning of insert should change
through the 'like Current' when the conformance in not supplied by current.
In the example:
* in the feature 'copy' the conformance of 'other' to COLLECTION fails
* the type of 'other' is 'like Current'
* 'copy' is an inserted feature (gained through 'insert LINKED_LIST')
Then in the environment of copy maybe it is possible to make 'Current' conform
to LINKED_LIST.
--------------
I have tried (in an opposite way of the one you tried with 'inherit ...
export ...') to insert LINKED_LIST and inherit COLLECTION this way
class STAFF_LIST
inherit COLLECTION[EMPLOYEE] undefine reverse end
insert LINKED_LIST[EMPLOYEE]
but i got the error
> ****** Fatal Error: Cannot pass `Current' which is of type STAFF_LIST
> into formal type LINKED_LIST[EMPLOYEE].
> Line 445 column 52 in LINKED_LIST (.../linked_list.e):
> create {ITERATOR_ON_LINKED_LIST[E]} Result.make(Current)
> ^
> Line 20 column 12 in ITERATOR_ON_LINKED_LIST (../iterator_on_linked_list.e):
> make (ll: LINKED_LIST[E]) is
> ^
because the feature 'get_new_iterator' of LINKED_LIST require the conformance
to LINKED_LIST of Current.
---------------
I suspect that many classes from the library and many classes that i will
write would not be easy to use through the insert mechanism because of the
current restriction on Current.
---------------
Then you reclaimed a third kind of inheritance and added it with the following
example:
> expanded class TWO_DECIMAL_DIGIT_INTEGER
> insert INTEGER
>
> invariant in_range : Current.in_range(10, 99);
> end
and here the error of SmartEiffel is
> ****** Fatal Error: You cannot inherit "INTEGER" (forbidden or not yet
implemented).
> Line 2 column 10 in TWO_DECIMAL_DIGIT_INTEGER
(.../two_decimal_digit_integer.e):
> insert INTEGER
> ^
(the error is the same if insert is replaced by inherit)
I really dont understand the error!!!
It seems to be temporary restriction of SmartEiffel.
---------------
For usual java developpers, that use the keyword 'extends', such a restriction
is not natural.
For example, one can imagine two inheritance order for integers:
inheritance that extends:
INTEGER_128 --> INTEGER_64 --> INTEGER_32 --> INTEGER_16 --> INTEGER_8
inheritance that restrict:
INTEGER_8 --> INTEGER_16 --> INTEGER_32 --> INTEGER_64 --> INTEGER_128
It seems that eiffel prefer restriction because it is usefull. However
integers are not chained through inheritance.
---------------
What you want for your third kind of inheritance is the restriction.
But when you inherit the integer you will have the same problem that above
with the type anchors.
Then you will have to redefine the basic methods to admit the integer
arguments. something like that:
class TWO_DECIMAL_DIGIT_INTEGER insert INTEGER ...
infix "+" (other: INTEGER): INTEGER ...
Because one can not restrict the precondition you can not ensure that the
result will be a TWO_DECIMAL_DIGIT_INTEGER so it must be an INTEGER.
I dont know if such a thing is usefull or not.
Personnally i use such kind of classes but i use the client relation not the
inheritance relation.
---------------
Maybe your idea of new kind of inheritance is good.
Maybe is it more a problem comming from type anchor to Current.
What Daniel said to be a problem relying to Current.
best regards
jb