=begin pod

=TITLE class Nil

=SUBTITLE Absence of a value or a benign failure

    class Nil is Cool { }

The value C<Nil> may be used to fill a spot where a value would normally
go, and in so doing, explicitly indicate that no value is present.  It
may also used as a cheaper and less explosive alternative to a
L<C<Failure>|/type/Failure>.

The class C<Nil> is the same exact thing as its only possible value, C<Nil>.

    say Nil === Nil.new         #-> True

Along with C<Failure>, C<Nil> is one of the two types which may
always be returned from a routine even when the routine specifies a
particular return type.  It may also be returned regardess of the
definedness of the return type, however, C<Nil> is considered undefined
for all other purposes.

    sub a ( --> Int:D ) { return Nil }
    a().say;                    #-> Nil

C<Nil> is what is returned from empty routines or clauses, or routines
that use a bare C<return> statement.

    sub a { }; a().say;         #-> Nil
    sub b { return }; b().say;  #-> Nil
    say (if 1 { });             #-> Nil
    { ; }().say;                #-> Nil
    say EVAL "";                #-> Nil

In a list, C<Nil> takes the space of one value.  Iterating a C<Nil>
behaves like iteration of any non-iterable value, producing a sequence
of one C<Nil>.

    (1,Nil,3).elems.say;        #-> 3
    (for Nil { $_ }).perl.say;  #-> (Nil,)

Any method call on C<Nil> other than those specifically listed below,
and consequently, any subscripting operation, will succeed and return
C<Nil>.

    say Nil.ITotallyJustMadeThisUp;  #-> Nil
    say (Nil)[100];                  #-> Nil
    say (Nil){100};                  #-> Nil

When assigned, a C<Nil> evaporates into the type object of the type
of the container you assigned it into.

    my Int $x = 42;
    $x = Nil;
    $x.say;                     #-> (Int)

Because an untyped variable is type C<Any>, assigning a C<Nil> to one
will result in an L<(Any)> type object.

    my $x = Nil;
    $x.say;          #-> (Any)
    my Int $y = $x;  # error:  Type check failed in assignment to '$y';
                     # expected 'Int' but got 'Any'

If you are looking for a variable which transforms objects into type objects
when said variable appears on the RHS, you can type the container as C<Nil>.

    my Nil $x;
    my Str $s = $x;
    $s.say;          #-> (Str)

There is an important exception to this transforms-into-type-object rule:
assigning C<Nil> to a variable which has a default will restore that default.

    my Int $x is default(42) = -1;
    my $y = 1;
    for $x,$y -> $val is rw { $val = $reset unless $val > 0 }
    $x.say;          #-> 42

=head1 Methods

=head2 method append

    method append(*@)

Warns the user that they tried to append onto a C<Nil>.

=head2 method gist

    method gist() returns Str:D

Returns C<"Nil">.

=head2 method Str

    method Str()

Warns the user that they tried to stringify a C<Nil>.

=head2 method new

    method new (*@)

Returns C<Nil>

=head2 method prepend

    method prepend(*@)

Warns the user that they tried to prepend onto a C<Nil>.

=head2 method push

    method push(*@)

Warns the user that they tried to push onto a C<Nil>.

=head2 method unshift

    method unshift(*@)

Warns the user that they tried to unshift onto a C<Nil>.

=head2 method new

    method new()

Returns C<Nil>.

=head2 method Numeric

    method Numeric()

Warns the user that they tried to numify a C<Nil>.

=end pod

# vim: expandtab shiftwidth=4 ft=perl6
