Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
define coercion types, value/impl types better
We were using two different meanings of "value type", so now
value vs implementation type is "of" type vs "container" type.

We also now have a coercive type syntax, so there's no longer
any need for a separate 'as' trait for subs.
  • Loading branch information
TimToady committed Aug 8, 2011
1 parent 5f35620 commit 35e20e2
Showing 1 changed file with 44 additions and 28 deletions.
72 changes: 44 additions & 28 deletions S02-bits.pod
Expand Up @@ -13,8 +13,8 @@ Synopsis 2: Bits and Pieces

Created: 10 Aug 2004

Last Modified: 2 Aug 2011
Version: 236
Last Modified: 8 Aug 2011
Version: 237

This document summarizes Apocalypse 2, which covers small-scale
lexical items and typological issues. (These Synopses also contain
Expand Down Expand Up @@ -515,6 +515,25 @@ You can pass in arguments to the constructor as well:
my Dog $cerberus .= new(heads => 3);
my Dog $cerberus = $cerberus.new(heads => 3); # same thing

=head2 Coercive type declarations

The parenthesized form of type coercion may be used in declarations
where it makes sense to accept a wider set of types but coerce them
to a narrow type. (This only works for one-way coercion, so you
may not declare any C<rw> parameter with a coercive type.) The type
outside the parens indicates the desired end result, and subsequent
code may depend on the it being that type. The type inside the parens
indicates the acceptable set of types that are allowed to be bound or
assigned to this location via coercion. If the wide type is omitted,
C<Any> is assumed. In any case, the wide type is only indicative of
permission to coerce; there must still be an available coercion routine
from the wide type to the narrow type to actually perform the coercion.

sub foo (Str(Any) $y) {...}
sub foo (Str() $y) {...} # same thing

my Num(Cool) $x = prompt "Gimme a number";

=head2 Containers of Native Types

If you say
Expand Down Expand Up @@ -1545,60 +1564,57 @@ a notable exception.

See L<S06/"Wrapping"> for a discussion of soft vs. hard routines.

=head2 Value types
=head2 Of types

Explicit types are optional. Perl variables have two associated types:
their "value type" and their "implementation type". (More generally, any
container has an implementation type, including subroutines and modules.)
The value type is stored as its C<of> property, while the implementation
their "of type" and their "container type". (More generally, any
container has a container type, including subroutines and modules.)
The of type is stored as its C<of> property, while the container
type of the container is just the object type of the container itself.
The word C<returns> is allowed as an alias for C<of>.

The value type specifies what kinds of values may be stored in the
variable. A value type is given as a prefix or with the C<of> keyword:
The of type specifies what kinds of values may be stored in the
variable. An of type is given as a prefix or with the C<of> keyword:

my Dog $spot;
my $spot of Dog;

In either case this sets the C<of> property of the container to C<Dog>.

Subroutines have a variant of the C<of> property, C<as>, that sets
the C<as> property instead. The C<as> property specifies a
constraint (or perhaps coercion) to be enforced on the return value (either
by explicit call to C<return> or by implicit fall-off-the-end return).
This constraint, unlike the C<of> property, is not advertised as the
type of the routine. You can think of it as the implicit type signature of
the (possibly implicit) return statement. It's therefore available for
type inferencing within the routine but not outside it. If no C<as> type
is declared, it is assumed to be the same as the C<of> type, if declared.

sub get_pet() of Animal {...} # of type, obviously
sub get_pet() returns Animal {...} # of type
our Animal sub get_pet() {...} # of type
sub get_pet() as Animal {...} # as type

A value type on an array or hash specifies the type stored by each element:
An of type on an array or hash specifies the type stored by each element:

my Dog @pound; # each element of the array stores a Dog

my Rat %ship; # the value of each entry stores a Rat

The key type of a hash may be specified as a shape trait--see S09.

=head2 Implementation types
Containers enforce type safety on setting, whereas subroutines enforce type
safety on return. The C<returns> declarations is an alias for the C<of> type
of a subroutine.

sub get_pet() of Animal {...} # of type, obviously
sub get_pet() returns Animal {...} # of type
our Animal sub get_pet() {...} # of type

To coerce your return value, use a coercion type:

sub get_pet() returns Pet(Animal) {...} # coerce any Animal to Pet

=head2 Container types

The implementation type specifies how the variable itself is implemented. It is
The container type specifies how the variable itself is implemented. It is
given as a trait of the variable:

my $spot is Scalar; # this is the default
my $spot is PersistentScalar;
my $spot is DataBase;

Defining an implementation type is the Perl 6 equivalent to tying
Defining a container type is the Perl 6 equivalent to tying
a variable in Perl 5. But Perl 6 variables are tied directly at
declaration time, and for performance reasons may not be tied with a
run-time C<tie> statement unless the variable is explicitly declared
with an implementation type that does the C<Tieable> role.
with a container type that does the C<Tieable> role.

However, package variables are always considered C<Tieable> by default.
As a consequence, all named packages are also C<Tieable> by default.
Expand Down

0 comments on commit 35e20e2

Please sign in to comment.