| Currently, Arc is pretty firmly embedded in the "is-a" thinking. An object currently has one, and only one, type, and it always "is-a" that type. On the other hand, statically typed languages have started to move from simple is-a inheritance towards has-a interfacing. For example, Haskell's types don't actually inherit from one another - instead, each type may belong to 0 or more type classes. Membership in a type class means that the type must provide the functions belonging to the type class - a type which belongs to a type class "has-a" that type class. An object is-a type, but that type has-a (possibly 0, possibly multiple) type class I wonder if a dynamically-typed language would be able to usefully make use of a formal has-a semantics. In my experiments with user-defined types - file-table, scanner, and bidir-table - I always had to redefine 'isa, or at least hack around it. This is because some polymorphic arc.arc stuff - notably 'each - don't really work well with duck typing. They expect a specific type, and will only work on that type. In order to make my user-defined types work well with the arc.arc builtins, I had to hack around 'isa. So I think we should really be using "has-a" semantics. For example, we can define that an object that "has-a" 'table interface must be able to provide methods for 'apply (as in (ob 'foo)), 'sref (as in (= (ob 'foo) 42)), and 'keys (as in, hmm, (keys ob)). It's is-a shouldn't actually matter to the basic arc.arc builtins; as long as the object somehow manages to support these functions, then as far as arc.arc is concerned it has-a way of working with the new types. This probably means that we have a type system that is nearer to has-a type classes/interfaces than is-a type. An object might be is-a string-scanner underneath, but as long as it has-a 'car and 'cdr method then map should work on it, each should work on it, applying it to a function should work on it. And of course 'each must dispatch based on whether the object has-a scanner or table interface. This isn't a "just for completeness" onion. It's plenty useful to be able to use the built-in (ontable ...) on a file-table, for example. If I suspect that file-table has a bug, I might instead use 'table to check. Or if I suddenly worry that someone might be reading my stuff I might build crypt-file-table. Or if the boss insists I can build db-table. And I want to rebuild as little as possible between modifications. That said, the current system (overloading 'isa, and more recently with scanners also 'acons and 'alist) works, and works well. It just doesn't feel like it works right; it's like the fact that it works is immaterial. |