On Mar 25, 12:35 pm, Konrad Hinsen <konrad.hin...@laposte.net> wrote: > On 25.03.2009, at 10:13, Mark Engelberg wrote: > > > 1. Structs don't inherently have a type. If you want to dispatch on > > type (a common use-case), you have to make a constructor that inserts > > the type information as part of the struct. Some have expressed > > And/or in the metadata. > > > concern that it may be too easy for this "type information" to be > > altered, or worse, the data could be "changed" or "removed" in a way > > that makes the struct inconsistent with the type label it carries > > around. > > I am one of those who have expressed concerns, but I must also say > that until now I have not encountered such a problem in real life. I > have come to the conclusion that interfaces and types work > differently in Clojure than in other languages that most of us are > more familiar with. So perhaps we are expecting problems that really > aren't there once you figure out how to do it "right". > > > 2. No way to call "next-method" or "super", which limits the ability > > to reuse related methods. > > Again, I'd like to see a real-life situation where this is an issue. > > > 3. The dispatch mechanism requires a lot of explicit prefer-methods, > > or else it may be hard to guarantee you won't get a run-time error > > from a situation the dispatch system considers ambiguous. This also > > And there as well. > > > makes code less extensible because to add a method, you must know > > about all the other methods that have been implemented in order to > > insert all the appropriate preferences. > > This would only be an issue in complex hierarchies. As long as each > library just adds its types to a hierarchy and implements methods for > them, there is no problem. That's why I'd like to see the real-life > situation where there is one. I repeatedly ran into all the problems Mark mentioned when trying to write an extensible set of codecs for serializing and deserializing game data, and for building a extensible set of data structures for representing game state. The game in question is a relatively large multiplayer RPG-style game whose data library needs to describe a large number of different kinds of objects, support transfer of those objects over networks and storage and retrieval on various kinds of repositories, and which needs to be extended by a number of people on an ongoing basis. I need to be able to clearly say what the protocols are for creating existing objects, and for defining new kinds of objects, and for serializing and deserializing them. With a large number of types of objects, name collisions in field- names becomes an issue. I can solve it by providing a mechanism to define the names allowed in a particular kind of object, and a way to declare requirements about the values allowed on those names. Storing type tags in metadata is handy in that the type function then returns the tag you want, and it's easy to make MultFns dispatch on those values. On the other hand, not all objects that one might want to dispatch on support metadata. That leaves storing type tags in the object itself, which is fairly convenient, but as the disadvantages Mark mentions. A partial workaround is to implement a feature for decalring the fields allowed and required in maps, and to implement consistency checking to ensure (to the extent that one can) that no one uses the type-tag field for anything other than type-tags. It's possible to provide a polymorphic API that covers each of the various defined kinds of objects, but building that API involves a lot of prefer-method calls. The inconvenience of that necessity increases, seemingly without bound, as people add new kinds of objects and methods to handle them. Each addition potentially requires its implementor to examine an ever-increasing set of previously-defined data descriptions and methods to determine what the correct prefer- method calls are. There may not always be a correct set. When there isn't, finding the data description and method definition that cause the unsolvable problem isn't necessarily easy. I'm extremely uncomfortable with any library that requires its user to be familiar with all of its internals and all its dependencies; that's exactly what libraries are meant to avoid. Therefore I am even more uncomfortable with library-building tools that guarantee that's the sort of library I'll be building. The set of game data objects describes features of an imaginary world. Those features (creatures, crafted items, factions, and so on) naturally cluster into related taxonomies of shared and specialized features. If you can say "this is just like those things except for these features", you save a lot of duplicated code. Type extension is one part of that ability; next-method is the other. This is one "real-world" situation where all the issues Mark raised are real and pressing issues for development, but it's not a special situation. I've run into these issues many many times over the years. They're why people keep on inventing mechanisms for type extension over and over, and why they keep coming up with various different ways to make protocols polymorphic. I ran into them almost twenty years ago, working on a fairly large automated system for machine control, written in a version of Common Lisp from before CLOS was widely adopted. That project solved these issues by using a homegrown object system. If the language doesn't provide type extension and robust polymorphism for protocols, its users will (assuming they keep using it). --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---