Author: larry Date: Thu Jan 3 16:15:39 2008 New Revision: 14479 Modified: doc/trunk/design/syn/S09.pod
Log: Clarification of autovivification semantics in terms of protoobjects Modified: doc/trunk/design/syn/S09.pod ============================================================================== --- doc/trunk/design/syn/S09.pod (original) +++ doc/trunk/design/syn/S09.pod Thu Jan 3 16:15:39 2008 @@ -12,9 +12,9 @@ Maintainer: Larry Wall <[EMAIL PROTECTED]> Date: 13 Sep 2004 - Last Modified: 10 Jul 2007 + Last Modified: 3 Jan 2008 Number: 9 - Version: 22 + Version: 23 =head1 Overview @@ -1160,9 +1160,12 @@ =head1 Autovivification -Autovivification will only happen if the vivifiable path is used as a -container, by binding, assigning, or capturing into an argument list. -On the other hand, value extraction does not autovivify. +Autovivification will only happen if the vivifiable path is bound to +a read-write container. Value extraction (that is, binding to a readonly +or copy container) does not autovivify. (Note that assignment +implicitly binds a copy, so it does not autovivify.) Any mention of +an expression within a C<Capture> delays the autovivification decision +to binding time. (Binding to a "ref" parameter also defers the decision.) This is as opposed to PerlĀ 5, where autovivification could happen unintentionally, even when the code looks like a non-destructive test: @@ -1176,17 +1179,62 @@ my %hash; exists %hash<foo><bar>; # %hash is still empty -But these ones I<do> autovivify: +But these bindings I<do> autovivify: my %hash; my $val := %hash<foo><bar>; my @array; - my $obj = [EMAIL PROTECTED]; # $obj is a Capture object - see S02 + my $cap = [EMAIL PROTECTED]; # $obj is a Capture object - see S02 + my :($obj) := $cap; # @array[0][0] created here + + my @array; + foo(@array[0][0]); + sub foo ($obj is rw) {...} # same thing, basically my %hash; %hash<foo><bar> = "foo"; # duh -This rule applies to C<Array>, C<Hash>, and C<Scalar> container objects. +This rule applies to C<Array>, C<Hash>, and any other container type that +chooses to return an autovivifiable protoobject (see S12) rather than simply +returning C<Failure> when a lookup fails. Note in particular that, since +autovivification is defined in terms of protoobjects rather than failure, +it still works under "use fatal". + +The type of the protoobject returned by a non-successful lookup should +be identical to the type that would be returned for a successful lookup. + +Binding of an autovivifiable protoobject to a non-writeable container +translates the protoobject into a similar protoobject without +its autovivifying closure and puts that new protoobject into the +container instead (with any pertinent historical diagnostic information +carried over). There is therefore no magical method you can call on +the readonly parameter that can magically autovivify the protoobject +after the binding. The newly bound variable merely appears to be a +simple uninitialized value. (The original protoobject retains its +closure in case it is rebound elsewhere to a read-write container.) + +Some implementation notes: Nested autovivifications work by making +nested protoobjects that depend on each other. In the general case +the containers must produce protoobjects any time they do not know +how the container will be bound. This includes when interpolated into +any capture that has delayed binding: + + \( 1, 2, %hash<foo><bar> ) # must defer + \%hash<foo><bar> # must defer + +In specific situations however, the compiler can know that a value +can only be bound readonly. For instance, C<< infix:<+> >> is +prototyped such that this can never autovivify: + + %hash<foo><bar> + 42 + +In such a case, the container object need not go through the agony +of calculating an autovivifying closure that will never be called. +On the other hand: + + %hash<foo><bar> += 42 + +binds the left side to a mutable container, so it autovivifies. =for vim:set expandtab sw=4: