Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 585 lines (421 sloc) 20.147 kB
be1862e P6 Synopsis : ws changes - to help BOMers, added leading blank line t…
Darren_Duncan authored
1
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
2 =encoding utf8
3
4 =head1 TITLE
5
42848cf IO.pod: Updated reference to Temporal.pod
wayland authored
6 Synopsis 14: Roles and Parametric Types [DRAFT]
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
7
04840a3 [Spec] treat all authors equally
lwall authored
8 =head1 AUTHORS
9
10 Larry Wall <larry@wall.org>
11 Tim Nelson <wayland@wayland.id.au>
12 Jonathan Worthington <jnthn@jnthn.net>
13
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
14 =head1 VERSION
15
04840a3 [Spec] treat all authors equally
lwall authored
16 Created: 24 Feb 2009 (extracted from S12-objects.pod)
17
907649f @TimToady dig up 'as' fossils found by fsergot++
TimToady authored
18 Last Modified: 25 Feb 2012
19 Version: 10
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
20
21 =head1 Overview
22
9c3a6e2 dos2unix
szabgab authored
23 This synopsis discusses roles and parametric types, which were
393fbca [spec] Tidying up, removing duplication and filling out S14.
jnthn authored
24 originally discussed in A12.
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
25
26 =head1 Roles
27
28 Classes are primarily in charge of object management, and only
ea2a000 [Spec]reverted \x20 to \xC2A0. "Perl 6" and "Perl 5" are words, so we…
jimmy authored
29 secondarily in charge of software reuse. In Perl 6, roles take over
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
30 the job of managing software reuse. Depending on how you care to look
31 at it, a role is like a partial class, or an interface with default
32 implementation, or a set of generic methods and their associated data,
33 or a class closed at compile time.
34
35 Roles may be composed into a class at compile time, in which case
36 you get automatic detection of conflicting methods. A role may also
37 be mixed into a class or object at run time to produce an anonymous
38 derived class with extra capabilities, but in this case conflicting
39 methods are overridden by the new role silently. In either case,
40 a class is necessary for instantiation--a role may not be directly
41 instantiated.
42
43 A role is declared like a class, but with a C<role> keyword:
44
45 role Pet {
46 method feed ($food) {
47 $food.open_can;
48 $food.put_in_bowl;
49 self.eat($food);
50 }
51 }
52
53 A role may not inherit from a class, but may be composed of other
54 roles. However, this "crony" composition is not evaluated until
55 class composition time. This means that if two roles bring in the
56 same crony, there's no conflict--it's just as if the class pulled in
57 the crony role itself and the respective roles didn't. A role may
58 never conflict with itself regardless of its method of incorporation.
59 A role that brings in two conflicting crony roles I<may> resolve them
60 as if it were a class. This solution is accepted by the class unless
61 the class supplies its own solution. If two different roles resolve
62 the same crony conflict two different ways, those roles are themselves
63 in conflict and must be resolved by a "more derived" role or the class.
64
65 A role doesn't know its own type until it is composed into a class.
66 Any mention of its main type (such as C<::?CLASS>) is generic, as is
67 any reference to C<self> or the type of the invocant. You can use
68 a role name as a type, but only for constraints, not for declaring
69 actual objects. (However, if you use a role as if it were a class,
70 an anonymous class is generated that composes the role, which provides
71 a way to force a role to test its crony composition for infelicities.)
72
73 If a role merely declares methods without defining them, it degenerates
74 to an interface:
75
76 role Pet {
77 method feed ($food) {...}
78 method groom () {...}
79 method scratch (:$where) {...}
80 }
81
82 Note that, while these methods must become available at class
83 composition time, they might be supplied by any of: another role,
84 the class itself, or some superclass. We know the methods that are
85 coming from the other roles or the class, but we don't necessarily know
86 the complete set of methods supplied by our super classes if they are
87 open or rely on wildcard delegation. However, the class composer is
88 allowed to assume that only currently declared superclass methods or
89 non-wildcard methods are going to be available. A stub can always
90 be installed somewhere to "supply" a missing method's declaration.
91
92 Roles may have attributes:
93
94 role Pet {
132ca18 [S14] use named arguments to .new() in an example
moritz authored
95 has $.collar = Collar.new(tag => Tag.new);
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
96 method id () { return $.collar.tag }
97 method lose_collar () { undefine $.collar }
98 }
99
100 Within a role the C<has> declarator always indicates the declaration
101 from the viewpoint of the class. Therefore a private attribute declared
9c3a6e2 dos2unix
szabgab authored
102 using C<has> is private to the class, not to the role. You may wish to
103 declare an attribute that is hidden even from the class; a completely
104 private role attribute (that will exist per instance of the class) may
393fbca [spec] Tidying up, removing duplication and filling out S14.
jnthn authored
105 be declared like this:
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
106
107 my $!spleen;
108
109 The name of such a private attribute is always considered lexically scoped.
110 If a role declares private lexical items, those items are private to
111 the role due to the nature of lexical scoping. Accessors to such
112 items may be exported to the class, but this is not the default.
113 In particular, a role may say
114
115 trusts ::?Class;
116
117 to allow C<self!attr()> access to the role's C<$!attr> variables with the
118 class or from other roles composed into the class. Conflicts between
119 private accessors are also caught at composition time, but of course
120 need not consider super classes, since no-one outside the current
121 class (or a trusted class) can call a private accessor at all.
122 (Private accessors are never virtual, and must be package qualified
123 if called from a trusted scope other than our own. That is, it's
124 either C<self!attr()> or C<$obj!TrustsMe::attr().>)
125
126 A role may also distinguish a shared method
127
128 has method foo ...
129 method foo ... # same
130
131 from a nonshared private method:
132
133 my method !foo ...
134 my method foo ... # same, but &foo is aliased to &!foo
135
136 Generally you'd just use a lexically scoped sub, though.
137
138 my sub foo ...
139
140 [Conjectural: To put a private sub into the class, say
141
142 our sub !foo ...
143
144 ]
145
146 A role can abstract the decision to delegate:
147
148 role Pet {
149 has $groomer handles <bathe groom trim> = hire_groomer();
150 }
151
152 Note that this puts the three methods into the class as well as
153 C<$groomer>. In contrast, "C<my $!groomer>" would only put the
154 three methods; the attribute itself is private to the role.
155
156 A role is allowed to declare an additional inheritance for its class when
157 that is considered an implementation detail:
158
159 role Pet {
e2dc809 [specs] add C<also> declarator to prefix any trait to be applied to t…
lwall authored
160 also is Friend;
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
161 }
30d53b2 [spec] some EOL conversion; set SVN props to avoid that in future
moritz authored
162
163 =head2 Compile-time Composition
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
164
165 A class incorporates a role with the verb "does", like this:
166
167 class Dog is Mammal does Pet does Sentry {...}
168
169 or equivalently, within the body of the class closure:
170
171 class Dog {
e2dc809 [specs] add C<also> declarator to prefix any trait to be applied to t…
lwall authored
172 also is Mammal;
173 also does Pet;
174 also does Sentry;
175 ...
176 }
177
178 or
179
180 class Dog {
181 also is Mammal does Pet does Sentry;
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
182 ...
183 }
184
185 There is no ordering dependency among the roles.
186
187 A class's explicit method definition hides any role definition of
188 the same name. A role method in turn hides any methods inherited
189 from other classes.
190
191 If there are no method name conflicts between roles (or with the
192 class), then each role's methods can be installed in the class. If,
193 however, two roles try to introduce a method of the same name the
194 composition of the class fails. (Two C<has> attributes of the same
8d8ebde [spec] Kill the same type = attribute composition OK rule; now it's j…
jnthn authored
195 name, whether public or private, are always a composition fail.
196 Role-private attributes are exempt from this, and from the viewpoint of
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
197 the composition, don't even exist, except to allocate a slot for each
198 such attribute.)
199
200 There are several ways to solve method conflicts. The first is simply to
201 write a class method that overrides the conflicting role methods, perhaps
202 figuring out which role method to call.
203
204 Alternately, if the role's methods are declared C<multi>, they can be
205 disambiguated based on their long name. If the roles forget to declare
206 them as multi, you can force a multi on the roles' methods by installing
207 a proto stub in the class being constructed:
208
209 proto method shake {...}
210
211 (This declaration need not precede the C<does> clause textually, since
212 roles are not actually composed until the end of the class definition,
213 at which point we know which roles are to be composed together
214 in a single logical operation, as well as how the class intends to
215 override the roles.)
216
217 The proto method will be called if the multi fails:
218
219 proto method shake { warn "They couldn't decide" }
30d53b2 [spec] some EOL conversion; set SVN props to avoid that in future
moritz authored
220
221 =head2 Run-time Mixins
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
222
223 Run-time mixins are done with C<does> and C<but>. The C<does> binary
224 operator is a mutator that derives a new anonymous class (if necessary)
225 and binds the object to it:
226
227 $fido does Sentry
228
229 The C<does> infix operator is non-associative, so this is a syntax error:
230
231 $fido does Sentry does Tricks does TailChasing does Scratch;
232
233 You can, however, say
234
235 $fido does Sentry;
236 $fido does Tricks;
237 $fido does TailChasing;
238 $fido does Scratch;
239
240 And since it returns the left side, you can also say:
241
242 ((($fido does Sentry) does Tricks) does TailChasing) does Scratch;
243
244 Unlike the compile-time role composition, each of these layers on a new
245 mixin with a new level of inheritance, creating a new anonymous class
246 for dear old Fido, so that a C<.chase> method from C<TailChasing> hides a
247 C<.chase> method from C<Sentry>.
248
249 You can also mixin a precomposed set of roles:
250
251 $fido does (Sentry, Tricks, TailChasing, Scratch);
252
253 This will level the playing field for collisions among the new
254 set of roles, and guarantees the creation of no more than one more
255 anonymous class. Such a role still can't conflict with itself, but it
256 can hide its previous methods in the parent class, and the calculation
257 of what conflicts is done again for the set of roles being mixed in.
258 If you can't do compile-time composition, we strongly recommend this
259 approach for run-time mixins since it approximates a compile-time
260 composition at least for the new roles involved.
261
262 A role applied with C<does> may be parameterized with an initializer
263 in parentheses, but only if the role supplies exactly one attribute
264 to the mixin class:
265
266 $fido does Wag($tail);
267 $line does taint($istainted);
30d53b2 [spec] some EOL conversion; set SVN props to avoid that in future
moritz authored
268
269 Note that the parenthesized form is I<not> a subroutine or method call.
270 It's just special initializing syntax for roles that contain a single
271 property.
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
272
11edda7 [spec] Update S14 with new semantics for when a value appears on the …
jnthn authored
273 The supplied initializer will be coerced to the type of the attribute.
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
274 Note that this initializer is in addition to any parametric type
275 supplied in square brackets, which is considered part of the actual
276 type name:
277
393fbca [spec] Tidying up, removing duplication and filling out S14.
jnthn authored
278 $myobj does Array[Int](@initial)
30d53b2 [spec] some EOL conversion; set SVN props to avoid that in future
moritz authored
279
280 A property is defined by a role like this:
281
282 role answer {
283 has Int $.answer is rw = 1;
284 }
285
286 The property can then be mixed in or, alternatively, applied using the
287 C<but> operator. C<but> is like C<does>, but creates a copy and mixes into
288 that instead, leaving the original unmodified. Thus:
289
290 $a = 0 but answer(42)
291
292 Really means something like:
293
294 $a = ($anonymous = 0) does answer(42);
295
296 Which really means:
297
298 (($anonymous = 0) does answer).answer = 42;
299 $a = $anonymous;
300
301 Which is why there's a C<but> operator.
302
303 If you put something that is not a role on the right hand side of the
304 C<does> or C<but> operators then an anonymous role will be auto-generated
305 containing a single method that returns that value. The name of the method
306 is determined by doing .WHAT.perl on the value supplied on the RHS. The
307 generated role is then mixed in to the object. For example:
308
309 $x does 42
310
311 Is equivalent to:
312
313 $x does role { method Int() { return 42 } }
314
315 Note that the role has no attributes and thus no storage; if you want that,
316 then you should instead use:
317
318 $x does Int(42)
319
320 Which mixes in the Int role and initializes the single storage location Int
321 that it declares with 42, and provides an lvalue accessor.
322
323 Note that .WHAT on an enumeration value stringifies to the name of the
11edda7 [spec] Update S14 with new semantics for when a value appears on the …
jnthn authored
324 enumeration, and as a result:
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
325
326 0 but True
327
30d53b2 [spec] some EOL conversion; set SVN props to avoid that in future
moritz authored
328 Is equivalent to:
329
11edda7 [spec] Update S14 with new semantics for when a value appears on the …
jnthn authored
330 0 but role { method Bool() { return True } }
30d53b2 [spec] some EOL conversion; set SVN props to avoid that in future
moritz authored
331
332 And thus the resulting value will be considered true in boolean context.
333
334 The list syntax for composing multiple roles in a single C<does> or C<but>
335 by putting them in a list also applies here. Thus:
336
337 42 but ("the answer", False)
338
339 Is equivalent to:
340
341 42 but (role { method Str() { return "the answer" } },
342 role { method Bool() { return False } })
343
344 Which gives you a compact way to build context-sensitive return values.
345 Note that multiple roles rather than a single one are generated, so that
346 anything like:
347
348 42 but (True, False)
349
350 Will fail as a result of standard role composition semantics (because two
351 roles are both trying to provide a method Bool).
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
352
353 =head1 Traits
354
04840a3 [Spec] treat all authors equally
lwall authored
355 Traits are just properties (roles) applied to something that is being declared (the I<declarand>),
356 such as containers or classes. It's the declaration of the item itself that
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
357 makes traits seem more permanent than ordinary properties. In addition
358 to adding the property, a trait can also have side effects.
359
360 Traits are generally applied with the "is" keyword, though not always.
361 To define a trait handler for an "is xxx" trait, define one or
362 more multisubs into a property role like this:
363
364 role xxx {
365 has Int $.xxx;
0079930 @moritz [S14] use :U instead of "where {!.defined}"
moritz authored
366 multi trait_mod:<is>(::?CLASS:U $declarand, :$xxx!) {...}
0638c11 [S14] a slightly closer approximation to eventual reality
lwall authored
367 multi trait_mod:<is>(Any $declarand, :$xxx!) {...}
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
368 }
369
370 Then it can function as a trait. A well-behaved trait handler will say
371
04840a3 [Spec] treat all authors equally
lwall authored
372 $declarand does xxx($arg);
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
373
04840a3 [Spec] treat all authors equally
lwall authored
374 somewhere inside to set the metadata on the declarand correctly.
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
375 Since a class can function as a role when it comes to parameter type
376 matching, you can also say:
377
378 class MyBase {
0079930 @moritz [S14] use :U instead of "where {!.defined}"
moritz authored
379 multi trait_mod:<is>(MyBase:U $declarand, MyBase $base) {...}
0638c11 [S14] a slightly closer approximation to eventual reality
lwall authored
380 multi trait_mod:<is>(Any $declarand, MyBase $tied) {...}
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
381 }
382
383 These capture control if C<MyBase> wants to capture control of how it gets
384 used by any class or container. But usually you can just let it call
385 the generic defaults:
386
0079930 @moritz [S14] use :U instead of "where {!.defined}"
moritz authored
387 multi trait_mod:<is>(Any:U $declarand, $base) {...}
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
388
04840a3 [Spec] treat all authors equally
lwall authored
389 which adds C<$base> to the "isa" list of class C<$declarand>, or
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
390
0638c11 [S14] a slightly closer approximation to eventual reality
lwall authored
391 multi trait_mod:<is>(Any $declarand, $tied) {...}
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
392
04840a3 [Spec] treat all authors equally
lwall authored
393 which sets the "tie" type of the container declarand to the implementation type
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
394 in C<$tied>.
395
04840a3 [Spec] treat all authors equally
lwall authored
396 Most traits are really just adverbial pairs which, instead of being
397 introduce by a colon, are introduced by a (hopefully) more readable
398 "helping verb", which could be something like "C<is>", or "C<will>", or
399 "C<can>", or "C<might>", or "C<should>", or "C<does>". Any trait verb
400 that is parsed the same as trait_mod:<is> may be defined the same way.
401 Here's "C<will>", which (being syntactic sugar) merely delegates to
402 back to "is":
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
403
0638c11 [S14] a slightly closer approximation to eventual reality
lwall authored
404 multi sub trait_mod:<will>($declarand, :$trait) {
405 trait_mod:<is>($declarand, :$trait);
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
406 }
407
04840a3 [Spec] treat all authors equally
lwall authored
408 Other traits are applied with a single word, and require special
907649f @TimToady dig up 'as' fossils found by fsergot++
TimToady authored
409 parsing. For instance, the "C<of>" trait is defined something
04840a3 [Spec] treat all authors equally
lwall authored
410 like this:
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
411
907649f @TimToady dig up 'as' fossils found by fsergot++
TimToady authored
412 role of {
413 has ReturnType $.of;
414 multi sub trait_mod:<of>($declarand, ReturnType $arg) is parsed /<typename>/ {
415 $declarand does of($arg);
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
416 }
417 ...
418 }
419
420 Unlike compile-time roles, which all flatten out in the same class,
421 compile-time traits are applied one at a time, like mixin roles.
04840a3 [Spec] treat all authors equally
lwall authored
422 You can, in fact, apply a trait to an object at run time, but
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
423 if you do, it's just an ordinary mixin role. You have to call the
04840a3 [Spec] treat all authors equally
lwall authored
424 appropriate C<trait_mod:<is>()> routine yourself if you want it to
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
425 do any extra shenanigans. The compiler won't call it for you at run
426 time like it would at compile time.
9c3a6e2 dos2unix
szabgab authored
427
798764b [S14] note (again) that macro syntax must be lexically scoped
lwall authored
428 Note that the declarations above are insufficient to install new trait
45ca8c8 @patch fix typos
patch authored
429 auxiliaries or verbs into the user's grammar, since macro definitions
798764b [S14] note (again) that macro syntax must be lexically scoped
lwall authored
430 are lexically scoped, and in the declarations above extend only to
431 the end of the role definition. The user's lexical scope must somehow
432 have processed (or imported) a proto declaration introducing the new
433 syntax before it can be parsed correctly. (This doesn't apply to
434 pre-existing syntax such as C<is>, of course.)
393fbca [spec] Tidying up, removing duplication and filling out S14.
jnthn authored
435
436 =head1 Parametric Roles
437
9c3a6e2 dos2unix
szabgab authored
438 A role's main type is generic by default, but you can also parameterize
439 other types explicitly using type parameters:
440
441 role Pet[::Petfood = TableScraps] {
442 method feed (Petfood $food) {...}
443 }
444
445 (Note that in this case you must not use ::Petfood in the inner declaration,
446 or it would rebind the type to type of the actual food parameter.)
447
448 If you want to parameterize the initial value of a role attribute,
449 be sure to put a double semicolon if you don't want the parameter to
450 be considered part of the long name:
451
452 role Pet[::ID;; $tag] {
453 has ID $.collar .= new($tag);
454 }
455
456 You don't just have to parameterize on types; any value is fine. Imagine
457 we wanted to factor out a "greet" method into a role, which takes
393fbca [spec] Tidying up, removing duplication and filling out S14.
jnthn authored
458 somebody's name and greets them. We can parameterize it on the greeting.
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
459
b458765 indent examples
lwall authored
460 role Greet[Str $greeting] {
461 method greet() { say "$greeting!"; }
462 }
463 class EnglishMan does Greet["Hello"] { }
464 class Slovak does Greet["Ahoj"] { }
465 class Lolcat does Greet["OH HAI"] { }
466 EnglishMan.new.greet(); # Hello
467 Slovak.new.greet(); # Ahoj
468 Lolcat.new.greet(); # OH HAI
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
469
470 Similarly, we could do a role for requests.
471
b458765 indent examples
lwall authored
472 role Request[Str $statement] {
473 method request($object) { say "$statement $object?"; }
474 }
475 class EnglishMan does Request["Please can I have a"] { }
476 class Slovak does Request["Prosim si"] { }
477 class Lolcat does Request["I CAN HAZ"] { }
478 EnglishMan.new.request("yorkshire pudding");
479 Slovak.new.request("borovicka");
480 Lolcat.new.request("CHEEZEBURGER");
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
481
9c3a6e2 dos2unix
szabgab authored
482 Sadly, the Slovak output sucks here. Borovicka is the nominative form
483 of the word, and we need to decline it into the accusative case. But
484 some languages don't care about that, and we don't want to have to make
485 them all supply a transform. Thankfully, you can write many roles with
486 the same short name, and a different signature, and multi-dispatch will
487 pick the right one for you (it is the exact same dispatch algorithm used
393fbca [spec] Tidying up, removing duplication and filling out S14.
jnthn authored
488 by multi-subs). So we can write:
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
489
b458765 indent examples
lwall authored
490 role Request[Str $statement] {
491 method request($object) { say "$statement $object?"; }
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
492 }
b458765 indent examples
lwall authored
493 role Request[Str $statement, &transform] {
494 method request($object) {
495 say "$statement " ~ transform($object) ~ "?";
496 }
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
497 }
b458765 indent examples
lwall authored
498 module Language::Slovak {
499 sub accusative($nom) {
500 # ...and before some smartass points it out, I know
501 # I'm missing some of the masculine animate declension...
502 return $nom.subst(/a$/, 'u');
503 }
504 }
505 class EnglishMan does Request["Please can I have a"] { }
506 class Slovak does Request["Prosim si", &Language::Slovak::accusative] { }
507 class Lolcat does Request["I CAN HAZ"] { }
508 EnglishMan.new.request("yorkshire pudding");
509 Slovak.new.request("borovicka");
510 Lolcat.new.request("CHEEZEBURGER");
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
511
9c3a6e2 dos2unix
szabgab authored
512 Which means we can now properly order our borovicka in Slovakia, which
513 is awesome. Until you do it in a loop and find the Headache['very bad']
393fbca [spec] Tidying up, removing duplication and filling out S14.
jnthn authored
514 role got mixed into yourself overnight, anyway...
515
9c3a6e2 dos2unix
szabgab authored
516 =head2 Relationship Between of And Types
517
518 The of keyword is just syntactic sugar for providing a single
519 parameter to a parametric type. Thus:
520
521 my Array of Recipe %book;
522
523 Actually means:
524
525 my Array[Recipe] %book;
526
527 This can be nested, so:
528
529 my Hash of Array of Recipe @library;
530
531 Is just:
532
533 my Hash[Array[Recipe]] @library;
534
535 Therefore:
536
537 my Array @array;
538
539 Means an Array of Array (actually, a Positional of Array).
540
541 =head2 Parametric Subtyping
542
543 If you have two types in a subtyping relationship such that T1 is
544 narrower than T2, then also the roles:
545
546 role R[::T] { }
547 role R[::T1, ::T2] { }
548
549 Will act such that R[T1] is narrower than R[T2]. This extends to multiple
550 parameters, however they must all be narrower or the same (this is unlike
551 in multiple dispatch where you can have one narrower and the rest narrower
552 or tied). That is, assuming we have some unrelated type T3, then R[T2, T1]
553 is narrower than R[T1,T1] but R[T2,T1] is not narrower than R[T1,T3].
554
555 Nesting follows naturally from this definition, so a role R[R[T2]] is
556 narrower than a role R[R[T1]].
557
558 This all means that, for example, if you have a sub:
559
560 sub f(Num @arr) { ... }
561
562 Then you can also call it with an array of Int.
563
564 my Int @a = 1,2,3;
565 f(@a);
566
567 =head2 Interaction of typed and untyped data structures
568
569 Certainly so far as Perl 6.0.0 goes, only types that have been declared
570 on a container count in the type check. That is, if we have a sub:
571
572 sub f(Int @arr) { ... }
9d5a38d P6 Synopsis : ws changes - remove trailing spaces
Darren_Duncan authored
573
9c3a6e2 dos2unix
szabgab authored
574 And call it with any of:
575
576 f([1,2,3]);
577 my @a = 1,2,3;
578 f(@a);
579
580 Then neither of these calls will work. The type check is based on the
581 declared type of the array, and the content is unknown to the type
582 checker.
328c62a S29: s/Container.pod/Containers.pod/
wayland authored
583
584 =for vim:set expandtab sw=4:
Something went wrong with that request. Please try again.