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