On Jul 13, 2005, at 6:16 PM, chromatic wrote:

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.

Um...huh? Sorry, I'm not trying to be sarcastic, but I honestly don't understand how you can think that. There are things that you can do with an Int that you cannot do with an int, so how can this be a meaningless distinction? Or did I miss a decision saying that 'int' was just a request, and that 'int' data could freely be autoboxed into an Int if necessary? That's quite possible...I haven't reread the AESs in a long time and things change often enough that I admit to not having a solid grip on the current state.



Why does the internal
representation of data matter if the interface is the same?

It shouldn't, I agree. My point was that the interface to Int (the object) is not the same as the interface to int (the low-level representation). For example, last I heard this was one of the differences:

    Int foo = 0 but true;  #  no problem
    int foo = 0 but true;  #  problem!  nowhere to store the trait


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.

Excellent, so do I.  Our views are not that far apart after all.



  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.

Ok, but you're begging the question. I'm trying to illustrate my definition of the word "type"; it doesn't help for you to say 'it must conform to the type...' when 'type' is what I'm trying to define.

In my mind, 'class' is one component that goes into making up a type. So is 'where clause'. So is 'roles that have been composited in'. Etc. A 'type', in my mind anyway, is a promise about the interface and state (*) that something will provide. Here are some examples (illustrative, not definitive):

    int $a    # 4 bytes (on a 32-bit system), can't store traits
    Int $a    # Can do everything 'int' can do, can also store traits
Int $a where { 0 < $a < 7 } # Can do everything Int can do but value is between 0 and 7 exclusive

I would contend that that list contains 3 types but only one class (maybe two if you interpret the where clause as creating a new class).

Does this seem like a reasonable definition of 'type' to you? Because I think we need to make sure we're using the same terms before we continue this.

(*) I hestitated on whether to include the 'and state' clause there, but finally decided to leave it. In that clause, I am only referring to state that is either publicly visible (and therefore, arguably part of the interface), or that governs (and therefore constrains) the behavior of the interface. I am not including internal-only state.



Taking your final question out of order:

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"?

Because it is an assertion that 'This' will be something that behaves like a Dog, and has the exposed state that I expect to see from a Dog. In other words, I agree with you--it's all about the interface. The point I'm trying to make is that, from the recipient's point of view, all of these statements are exactly the same:

     implements the interface of Dog
 === is of class Dog
 === has been composited with the Role Dog

Given that, why do we need the second version? (Don't say 'TIMTOWTDI'. Extra WTDI are only useful if they have different nuances.)


Roles do have state.

Ok, I didn't realize that.  My bad.

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


I agree with all these points. I still don't understand why Roles need to be a separate thing, with a separate name and separate semantics. Their purpose is simply to define an interface so that you can do two things:

1) Make an object/class/etc that implements that interface and advertises that it does so 2) Constrain a parameter by requiring its argument to implement that interface

So, why does it matter whether we call the thing that implements that interface a "Role" or an "interface" or a "class"? Why not call it a "class" and get rid of the extra term, free up 'does' to be a constraining term, etc?

--Dks

Reply via email to