Xref: utzoo comp.lang.misc:7064 comp.object:2883 comp.lang.eiffel:1463 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!zaphod.mps.ohio-state.edu!rpi!uupsi!sunic!enea!sommar From: sommar@enea.se (Erland Sommarskog) Newsgroups: comp.lang.misc,comp.object,comp.lang.eiffel Subject: Re: CHALLENGE: typing and reusability Message-ID: <3090@enea.se> Date: 25 Mar 91 22:37:41 GMT References: <1991Mar22.210725.29448@neon.Stanford.EDU> Organization: Enea Data AB, Sweden Lines: 107 (For comp.lang.eiffel readers: there's been a long discussion going on in comp.lang.misc on dynamic vs. static typing.) As the first propoent of dynamic typing, Urs Hoelzle (hoelzle@neon.Stanford.EDU) gives us a concrete example where langauges with static typing is said to bite the dust. I have deferred the quote of his example to end of this article for new readers in comp.lang.eiffel. >** So, would everybody who does *NOT* believe that dynamically-typed ** >** languages can achieve greater reusability than today's statically-typed ** >** languages PLEASE post a solution to this (written in his/her favorite ** >** programming language)??? ** >... >I claim that this piece of code won't type-check in Ada, C++, Eiffel, ... Ada is out. But in Eiffel this is a piece of cake, however with one non-ignorable objection: we must change the inheritance structure. If we introduce a new class SUPER, preferably deferred (which means that no objects of this class be created), and make A and B heirs of SUPER, we can then define a list class which looks something like: class FOO_DISPLAY_LIST(T -> SUPER) -- () is easier to read than [] on my screen. export repeat LINKED_LIST, do_foo, display inherit LINKED_LIST -- or whichever list that's appropriate feature -- define iterators that call foo and display end We can now declare: ListA : FOO_DISPLAY_LIST(A); ListB : FOO_DISPLAY_LIST(B); ListC : FOO_DISPLAY_LIST(SUPER); Of course having to modify the existing classes with a common ancestor, may be out of the question, and the example says that A and B are unrelated. On the other hand, if they are going to be in the same list, they are no longer unrelated, are they? And remember that it does not suffice that they both understand Foo and Display, they have to understand them in the same way, i.e. they must have the same parameter profile in both classes. With adding the example code to our system, we do add a dependency between A and B, and in a dynamically typed language if we modify A or B we must run a test suite which covers all a referenses to A and B to enure we didn't break anything. Not only the test suite is labourous task to develop - albeit very useful in any environment - we still don't *know* that type or parameter-profile error will not occur, we can only assume. In a statically typed language, the compiler tells ensures us that these errors won't happen. Of course several other errors are still possible, but we are at least one worry shorter. Now, if modifying A and B is undesireable *and* this is a common scene, one could of course envision changes to Eiffel to alleviate the situation. One idea would be to allow a class to declare explicit heirs, which means that we could SUPER, but still leave A and B untouched. To help up our sleep at night, this sort of declaration would only be allowed in a deferred class. But to be frank, I don't find the reason for such a change compelling enough. I'm by no means an Eiffel expert, I would appreciate other Eiffel people's input on this. If you know the example, you can press "n" here. >====================== example ============================== >Assume the following types: > >type List = generic list; understands (among others) > 'concatenate': returns a new [generic] list which is the > concatenation of the two argument lists" > 'do': takes a procedure with one argument and applies it > to all elements of the list (i.e. a generic iterator) > >type FooType = "object that understands 'foo'" > >type A = some random application type, understands (among others) > 'foo' and 'display' > >type B = some other application type (completely unrelated to A), also > understands (among others) 'foo' and 'display' > >Also assume that there exists a procedure someProc(l:List of FooType) >which iterates through the list and may send 'foo' to some of its >elements. > >VAR listA: "list of objects of type A" >VAR listB: "list of objects of type B" >VAR listC: "see below" > >Now, the program you're writing has to do: > >listA := ... // some computation to fill the list >listB := ... // some computation to fill the list > >listC := listA.concatenate(listB); // make a new list containing As and Bs > >someProc(listC); // do the "foo thing" to the list > >listC.do(display); // display all elements of the list > >====================== end of example ========================= -- Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se