Newsgroups: comp.lang.eiffel,comp.object,comp.lang.modula3,comp.lang.sather,comp.lang.beta Path: news.daimi.aau.dk!news.uni-c.dk!sunic!news.funet.fi!news.csc.fi!news.eunet.fi!EU.net!howland.reston.ans.net!pipex!uknet!comlab.ox.ac.uk!sable.ox.ac.uk!lady0065 From: lady0065@sable.ox.ac.uk (David J Hopwood) Subject: Re: Cows, Hogs & Farms Message-ID: <1995Jan12.031516.22136@inca.comlab.ox.ac.uk> Sender: david.hopwood@lmh.oxford.ac.uk Organization: Oxford University Computing Service, 13 Banbury Rd, Oxford, UK References: <3eih36$94g@network.ucsd.edu> <1995Jan6.164948.4782@schbbs.mot.com> <1995Jan9.005627@hobbit> Date: Thu, 12 Jan 95 03:15:15 GMT Lines: 217 Xref: news.daimi.aau.dk comp.lang.eiffel:7158 comp.object:23716 comp.lang.modula3:3324 comp.lang.sather:1423 comp.lang.beta:216 In article <1995Jan9.005627@hobbit>, Mark S. Hathaway wrote: >> In article <1995Jan6.164948.4782@schbbs.mot.com>, >> shang@corp.mot.com (David L. Shang) writes: ... >>> You can do most of Cluster's static solution in Sather, and I guess Eiffel. >>> >>> ... >>> class MONOCULTUREFARM{FOODT, ANIMALT < $HERBIVORE{FOODT} } is >>> attr livestock : LIST{ANIMALT}; -- type is known at compile time >>> attr foodstock : LIST{FOODT}; -- type is known >>> ... > >Should there be a $FOOD abstract type used here ( "FOODT < $FOOD" )? Yes, that would be better. >Would there have to be an "include HERBIVORE" and maybe "include FOOD" >for this to work? No. That would only be needed if we wanted to copy the implementation of the classes HERBIVORE and FOOD, which is not the case here. >> This form is slightly different in semantics from the Cluster's form: >> >> class MONOCULTUREFARM [ANIMALT <: HERBIVORE] >> attr livestock : list[ANIMALT]; >> attr foodstock : list[ANIMALT.FOODT]; >> ----- (1) > >Does Cluster separate the subtyping and inheritance as Sather does? No. In Cluster subclassing implies subtyping. IMO this is not a good idea, because it is useful to be able to use part of the implementation of a class without subtyping from it. >Is the use of "ANIMALT <: HERBIVORE" a convenience or requirement? It is a requirement if you want to make ANIMALT a polymorphic type variable that can be referred to within MONOCULTUREFARM. (ANIMALT on its own would mean ANIMALT <: ANY, which is wrong in this case). >So, ANIMALT.FOODT implies that a particular food is associated with a >particular animal? Yes (more accurately, a particular type of food with a particular type of animal). >How can it be a HERBIVORE and yet eat only one kind >of plant? If ANIMALT is bound to exactly HERBIVORE, then the animals will eat any PLANT (ie. HERBIVORE.FOODT = PLANT) If it bound to a subtype of HERBIVORE, then they will eat a subtype of PLANT (eg. HOG.FOODT = CORN) >> or BETA's form: >> >> MONOCULTUREFARM >> (# ANIMALT :< HERBIVORE >> attr livestock : @list (# eleT::ANIMALT #); >> attr foodstock : @list (# eleT::ANIMALT.FOODT #); >> #) > >It's not especially readable, is it? Nope :-) >Is it really ":<" rather than Cluster's "<:"? Very funny contrarianism! Yep :-) >Since "ANIMALT :< HERBIVORE" is inside the "(#" & "#)" enclosure I wouldn't >guess you could create a MONOCULTUREFARM(COW). Yes you can (but I can't remember the syntax). >Since there's no "class" in front of "MONOCULTUREFARM" I'd guess that >everything in BETA is a class or pattern or somethin', huh? Yes (a pattern). >So, by having only one "form" it can be understood what this is. Is there >any special notation to differentiate a main program from these others? I don't know (I don't program much in BETA). The idea of a main program is only really needed at the end of development, and only then because you're running it from a non-OO environment. >Do any of these MONOCULTUREFARMs (Sather, Cluster or BETA) inherit >from FARM or are they the lowest base of farm that will exist in this >class hierarchy? It doesn't really matter. No other FARM types are being modelled in this example, but they could be. >[snipped a bunch] > >> It might be difficult to argue which way is better for a farm, but as I >> said, the language should at least give the way that the speaker wants. > >Yes, the language should provide a way to express something. That's why >I cringe when I see syntax like BETA's. :-) To be fair, orthogonality is very nice. But I think it could have been done in a little more user-friendly way, in the case of BETA. All those symbols give me a headache. >How about... > > class MonocultureFarm ( food is plant, animal is herbivore ) is > procedure feed (); > end MonocultureFarm; > > class MonocultureFarm body is > import list; > object livestock is list(animal); > foodstock is list(food); > procedure feed ( get livestock is in out list(animal); > get foodstock is in out list(food) ) is > begin > ... > end feed; > end MonocultureFarm; > > program temp is > import MonocultureFarm; > object myfarm is MonocultureFarm(corn,hog); > begin > myfarm.feed(); > end temp. Looks good to me. This sort of code would be valid in Cluster, Sather and BETA. The difference in Cluster et al, is that you can also say program temp is import MonocultureFarm; object myfarm is MonocultureFarm(myanimal, myfood); object currentanimal is myanimal; object currentfood is myfood; begin -- can refer to 'myanimal' and 'myfood' as type variables anywhere -- inside here. end temp. >Since it's not like a procedure within a module the parameters of >MonocultureFarm which are of type/class plant and herbivore aren't >"import"ed first. That's a little awkward, but these other languages >(BETA, Cluster, Sather) don't seem to need the "import". Is it no >longer regarded as necessary? Personally, I like explicitly importing things. It means you don't have cluttered global namespaces. But it's not strictly necessary. >> Back to the major difference: >> >> Cluster's generic class are real classes but Sather's is not. >> Therefore, by Cluster, HERBIVORE[GRASS] is a subclass/subtype >> of HERBIVORE. > >I hesitate to ask what kind of GRASS is an HERBIVORE. So you should. Personally, I find the way Cluster is being explained here rather obscure; I would prefer to consider HERBIVORE to refer to a module rather than a type (because it isn't qualified with a type parameter). The thing which is causing the confusion is that Cluster allows type parameters to be referred to either by name, or by position (a bit like function parameters in Ada83, if that helps). As far as I can make out, it also allows the following syntactic sugar: instead of declaring object foo is X [TYPETAG = T] -- where T is a type variable object bar is T you can say object foo is X -- the T is now implicit object bar is X.TYPETAG Using that sugar, you can claim that HERBIVORE [GRASS] (which is the same thing as HERBIVORE [FOODT = GRASS]), is a subtype of HERBIVORE. That is equivalent to introducing T as a local type variable, and saying that HERBIVORE [GRASS] is a subtype of HERBIVORE [T] for some T. I hope I haven't confused people utterly with that. >> By Sather, HERBIVORE[GRASS] cannot be a subclass/subtype of HERBIVORE. >> That's whay Sather cannot have the expression: >> >> ANIMALT < $HERBIVORE >> >> because HERBIVORE is not a class. > >I asked (above) if Sather would also have to use an "include HERBIVORE" to >comlete the equation. This comparison of Cluster's inheritance scheme to >Sather's asks the same question. The basic difference between Sather's genericity and Cluster's is that in Cluster (and BETA, Cecil, Trellis/Owl, and lots of functional languages), you can use type variables outside the particular class that defines them. The difference between Sather's inheritance and Cluster's is a separate issue; in Sather, subtyping is separated from inheritance (which is why you need include as a new construct), while in Cluster it is not. >If you're inheriting an HERBIVORE then how can it be an HERBIVORE that >only eats GRASS? It seems to me that the tying together of the specific >food(s) to the animal has to be done at a higher level of abstraction -- >probably in the algorithm which represents the farmer's actions. Exactly. To do this, you need to use type parameters within the farmer algorithm, not just within MONOCULTUREFARM. The resulting algorithm doesn't need to be instantiated with specific types in order to work correctly (as in Sather, C++, Ada-style genericity); there is only one algorithm, which can be used with its parameters bound either to type variables, or to specific types. Cluster et al allow you to do this; Sather et al don't. ... >Mark S. Hathaway David Hopwood david.hopwood@lmh.oxford.ac.uk