On Apr 29, 2009, at 5:00 PM, Zbigniew Lukasiak wrote:
First of all: OK - I understand that this was the official
interpretation. This is enough for me for continuing my work.
But see below for some more 'philosophical' notes.
On Wed, Apr 29, 2009 at 2:45 PM, Stevan Little
<stevan.lit...@iinteractive.com> wrote:
On Apr 29, 2009, at 5:48 AM, Zbigniew Lukasiak wrote:
It seems that in the Moose terminology a Type is just a constraint
with a name. This is different from other languages where the
type of
a value does not change in time or in relation to the whole system.
You can copy the value and be sure that the copy has the same type
you
can wait and check the value after some time and it's type would not
change, but if a value type is defined by it passing a constraint -
then these invariants do not hold. For example think about a
constraint that checks if a date is in the past.
Actually they are called "TypeConstraints" in the docs, sometimes
shorten to
just "types" for convenience, but we make no claims that this is a
full
fledged type system
(http://search.cpan.org/~drolsky/Moose-0.76/lib/Moose/Util/TypeConstraints.pm#Important_Caveat
).
The other languages you describe are statically typed languages
(Haskell,
OCaml, Ada) where the compiler has sufficient information to
perform an
analysis of all variables at compile time and assure that their
type usage
stays correct. Quite often actually these languages will actually
discard
type information once it has been statically verified at compile
time and
not actually perform any runtime checks (no need too, it is already
known it
is correct). I personally would love to be able to do this in Perl,
but is
probably not possible without re-writing parts of the core
interpreter.
I was not talking here about variables (where the 'statically typed'
term could be applied) I was talking about values.
Okay, I am kind of confused then.
If "foo" is a value whose type is a string, then (aside from the
automatic coercion into a number) Perl does this already.
Taking it one step further, {} is a value whose type is a hash. I can
mutate the hash, but does that change it's intrinsic type? It is still
a hash isn't it?
When I am speaking about variables, I am taking about "containers".
Where $x is a container that can hold a SCALAR value. Same goes for
%x, which is a container that can hold a hash. The value's inside
these containers can be changed, but $x will still just hold a SCALAR
and %x will still just hold a HASH. Different values, but same
containers.
This is why some people say perl is strongly typed, because $x will
always only hold a SCALAR, @x an ARRAY and %x a HASH. I tend to not
agree with this fact because all of perl's automatic coercion (my $x =
@x, etc) means that these "strong" types are not al that strong.
In my mind (CAVEAT: I am not a computer scientist or a professional
type theorist and I *fully* admit that the deeper parts of type theory
go *way* above my head, I am speaking on my (possibly wrong, possibly
right, probably somewhere in between) understanding of things only),
having types on values is not terribly useful. 1 will be 1 always, it
won't change. Same is true of (1, 2, 3), it will always be the same
value (you can't mutate it until you assign it into a variable). These
are literal values and their type will never change because they are
constant values.
Now, variables/containers are where it gets more interesting. But it
is 6pm EST and I am too hungry to dive into some long rant about type
stuff.
So, perhaps I am not understanding your use of "values" here. Can you
elaborate?
What Moose aims to provide is two things:
- A flexible and extensible way to compose types and subtypes
This is the "Type" part of the "TypeConstraints". This system is
modeled
partially on Perl 6 but largely on more formal type systems like
Haskell and
OCaml. The big difference between this and an OCaml/Haskell type
system is
that Ocaml/Haskell type definitions also function as type
constructors as
well as type checkers, ours are just type checkers.
Hmm - ok so my intuition of types and subtypes is that the two
sentences hold:
1. If a value has a type A that is a subtype of type B - then this
value is of type A
So again, I am not sure I get your usage of "value" here. But that
aside, if I understand correctly, in Moose, that might look like this:
type 'B' => where { ... };
subtype 'A' => as 'B' => where { ... };
Anything that passed the check for A would have also passed the check
for B. In fact, all the parent types must pass, then the type itself
must pass. Take a look here (http://cpansearch.perl.org/src/DROLSKY/Moose-0.76/lib/Moose/Util/TypeConstraints.pm
) and scroll down to the definitions of the core types. You will see
that they are arranged in a tree or sorts where Any is the catch-all
type (I think this is typically called the "bottom" type), the Item is
a subtype of Any, Defined is a subtype of Item, Value is a subtype of
Defined, etc etc on down the tree.
2. Every type is a subtype of itself
I don't understand that statement, can you please expand on it? Sounds
kinda like my favorite "Class is an instance of Class" statement that
"ties the knot" in the object system.
Now take DateInThePast - the same value (lets say 29th of April 2009)
can at one point have that type and at another point in time it will
not have that type.
Yes, okay, so this is a fine line and not really the best example
because unless you have a time machine the 29th of April 2009 will
always be a date in the past (well technically not until tomorrow, but
you get the point).
This is getting into (my understanding of) the world of dependent
types. This is types where the actual value is relevant to the type
definition and not just the "type" of the value. In this case
DateInThePast is of the type Date, but it's value (a date in the past)
is what you are more interest in.
Dependent types are pretty nutty things and I only just sorta feel
like I understand then, but not quite. I have seen some arguments that
basically declare them useless since to properly dependently type
check a program you could have execute the entire thing at compile
time (how else would you know the values themselves, not just their
types).
Anyway again, too hungry for heavy type theory and I am not really a
good resource here anyway.
The point is that in the Moose type system these sentences don't have
any meaning at all - because it is not the value that has the type.
Okay, so yeah sure. This is why it is a "type constraint" system. But
again I don't really get what is so interesting about knowing that 1
is a type Number, I think it is more useful to know that given $x = 1,
$x is currently holding a value which is of type Number and through
that $x is (sorta) of the type Number.
- Stevan
- A means of using these type constraints for validation
This is the "Constraint" part of the "TypeConstraints". The goal is
help
make it easy to use the types you define to check parameters (using
one of
the MooseX:: method modules) and/or object slot values (in core
Moose). All
type constraints are instances of Moose::Meta::TypeConstraint or a
subclass
of that, and they all respond to the basic ->check($value) method
(No magic
here folks).
---
So, the way you need to look at this really is not a type system
where types
are attached to a given variable for it's entire life, but a type
constraint
system where certain values can be checked at runtime to see if
they pass
the constraint. In other words, not "real" types.
The same as above - I am not talking about variables but about values.
--
Zbigniew Lukasiak
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/