Xref: utzoo comp.lang.misc:7047 comp.object:2870 Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!apple!agate!stanford.edu!leland.Stanford.EDU!leland.Stanford.EDU!hoelzle From: hoelzle@leland.Stanford.EDU (urs hoelzle) Newsgroups: comp.lang.misc,comp.object Subject: Re: CHALLENGE: heterogeneous collections Message-ID: <1991Mar25.220525.11087@leland.Stanford.EDU> Date: 25 Mar 91 22:05:25 GMT References: <22032@yunexus.YorkU.CA> <11820:Mar1923:59:3591@kramden.acf.nyu.edu> <19MAR91.22493670@uc780.umd.edu> <18271:Mar2013:19:1091@kramden.acf.nyu.edu> <1991Mar20.214231.3411@neon.Stanford.EDU> <1991Mar22.210725.29448@neon.Stanford.EDU> Sender: news@leland.Stanford.EDU (Mr News) Organization: AIR, Stanford University Lines: 57 In article , pallas@eng.sun.com (Joseph Pallas) writes: |> |> Sooner or later, opponents of static typing bring out the |> heterogeneous collection. |> [stuff deleted] |> The problem is, no one has ever come up with a convincing reason why I |> should want my type system to handle the heterogeneous collection. |> This is because no one has come up with a convincing reason why I |> should want to write programs that contain heterogeneous collections. |> Needing collections of otherwise-unrelated objects generally signals a |> flaw in the design, not a failing of the type system. I think a few clarifications are in order because you're attacking on the wrong front, Joe: 1. I am not an "opponent of static typing". For some kinds of problems, they have advantages, and for others they have disadvantages. But I do disagree with people who say that typing does not impair reusability, or who say "I can do that in , too". 2. Here's why you want at least some form of heterogeneous collections: type T = "some type" type SubT = "subtype of T" procedure someProc(c: List[T]) I think that you'll agree with me that you'd like to use someProc with a Collection[SubT], especially if someProc just iterates through the list and sends 'foo' -- after all, every SubT "is a" T. But as soon as Lists are mutable (e.g. define insert(newElem: T)), the type system won't let you do it because List[SubT] is *not* a subtype of List[T]. You could try to fix this by splitting List into ReadOnlyList and a subtype ReadWriteList (which adds the insert operation), but this begins to stretch the correspondence between types and concepts (IMHO). And it certainly doesn't scale up very well, e.g. when you try to subclass List or when you have several methods like "insert" which you need to "turn off" in order to use someProc. In a way, the problem exists because today's type systems are based on what you *could* do to the list in someProc, not on what you actually do. 3. At least for rapid prototyping, your argument that "the type hierarchy isn't perfect if this situation occurs" is invalid: you *don't* want to rearrange lots of types just to try something out. Instead, you want to combine existing functionality in new ways which you didn't anticipate when you originally wrote the code. When (and if) you convert your prototype into a "product", *then* you go back and clean up the type hierarchies. Even in "production" programming, life isn't perfect and you might not be able to rearrange the type hierarchy because a) you're using some library or b) different uses have conflicting views, i.e. require conflicting type hierarchies. -Urs