On Wed, 2005-07-13 at 17:33 -0400, David Storrs wrote: > > What is a type besides a named blob of methods > > and, possibly, data?
> A label that says how the data is stored internally. For example, > compare "Int" and "int". The former is a type and a blob of methods > and not necessarily abstract. The second is a type, is NOT a blob of > methods, and is definitely NOT abstract. I contend that that's meaningless to Perl. Why does the internal representation of data matter if the interface is the same? In Perl 5 terms, should you not be able to pass a tied hash to a module that expects a hash because the internal implementation may be very different? If yes, then we have very different ideas about types and signatures and I'm not sure we can reconcile our views. I realize that it could appear that I've shifted the example to container types away from your argument about value types, but I don't think it's an important distinction here. > Making people think about what they really want is a good idea. I agree, but only as far as what they really want is actually what they really want. To put it another way, if you have a method that prints something passed in, do you want a signature that says "This must be a string, perhaps with a specified encoding and internal representation" or a signature that says "This must be something that stringifies"? I want the latter. > Note that there are two subtly different kinds of type constraints > under discussion: the first is what class something is, and the > second is what behavior it can exhibit. I think the former is silly, almost always useless, and nearly always wrong, especially in library code. > The two are very slightly different: > > multi foo(Dog $x); # Must be of class > Dog, or a class that is a descendant of Dog No, I think it must conform to the type of Dog, whether it is an instance of the Dog class, an instance of a subclass of Dog, or something that performs the Dog role. Why does its internal implementation matter? What are you doing inside foo() that its internals matter? > multi foo(Dog $x where { not $x.feral }); # Must be of > anonymous class "class Dog (or descendant) with $.feral set to false" Again, I think it must conform to the type of Dog, but with the additional constraint. > The distinction I'm drawing is between pure behavior and behavior > +state. I'm drawing this based on the idea that Roles are not > allowed to have state--that they are pure virtuals, only used for > defining interface. If that is not true, then (A) I apologize for > the wasted bandwidth and (B) I'd like to have it explained what Roles > offer that justifies their existence, since they won't be anything > but a restricted form of a class. Roles do have state. They exist because: 1) hierarchies aren't the only way to express type relationships -- nor are they often even a good way 2) conformity to an interface is more important than uniformity of internal representation, especially in a language with late binding 3) non-hierarchical code-reuse is possible -- and very useful 4) making no distinction between class, role, and type names makes genericity and polymorphism much easier and much more powerful Aside from optimization and introspection, why is it useful for a method signature to say "This has to be a Dog or something that inherits from Dog"? -- c