=begin pod :kind("Type") :subkind("class") :category("composite")

=TITLE class Slip

=SUBTITLE A kind of List that automatically flattens into an outer container

    class Slip is List {}

A C<Slip> is a L<List|/type/List> that automatically flattens into an outer List
(or other list-like container or iterable).

For example it allows you to write a L<map|/routine/map> that produces more than
one value into the result without nesting:

=for code
say <a b c>.map({ ($_, $_.uc).Slip }).join('|');        # OUTPUT: «a|A|b|B|c|C␤»

In contrast, when returning an ordinary List, the resulting list is nested:

=for code
say <a b c>.map({ $_, $_.uc }).join('|');               # OUTPUT: «a A|b B|c C␤»

To create a C<Slip>, either coerce another list-like type to it by calling the
C<Slip> method, or use the C<slip> subroutine:

    # This says "1" and then says "2", rather than saying "(1 2)"
    .say for gather {
        take slip(1, 2);
    }

A C<Slip> may also be created by using the L«C<prefix:<|>>|/language/operators#prefix_|» operator.  This differs
from the C<slip> subroutine in both precedence and treatment of single
arguments. In fact, C<prefix:<|>> only takes a single argument, so in that way,
it behaves closer to the C<.Slip> method than the C<slip> subroutine.

=for code
my $l = (1, 2, 3);
say (1, slip 2, 3).raku;  # says (1, 2, 3)          , slips 2, 3 into (1, …)
say (0, slip $l, 4).raku; # says (0, $(1, 2, 3), 4) , $l does not break apart
say (0, slip $l).raku;    # says (0, 1, 2, 3)       , slips from $l into (0, …)
say (0, $l.Slip).raku;    # says (0, 1, 2, 3)       , slips from $l into (0, …)
say (0, $l.Slip, 4).raku; # says (0, 1, 2, 3, 4)    , slips from $l into (0, …, 4)
say (|$l).raku;           # says slip(1, 2, 3)      , breaks apart $l
say (0, (|$l, 4), 5);     # says (0 (1 2 3 4) 5)    , slips from $l into (…, 4)
say (0, ($l.Slip, 4), 5); # says (0 (1 2 3 4) 5)    , slips from $l into (…, 4)
say (0, (slip $l, 4), 5); # says (0 (1 2 3) 4 5)    , slips ($l, 4) into (0, …, 5)
say (0, ($l, 4).Slip, 5); # says (0 (1 2 3) 4 5)    , slips ($l, 4) into (0, …, 5)

Loops that do not want to produce a value for an iteration use C<Slips>, rather
than empty C<List>s to do so, as do C<if> statements that do not run their
blocks.

Please note that C<prefix:<|>> will also apply parameters in a slippy manner to
a routine call. It does not forward a C<Slip> to the called routine, that
includes C<return> and C<take>.

    my \l = gather for 1..10 -> $a, $b { take |($a, $b) }; say l.raku;
    # OUTPUT: «((1, 2), (3, 4), (5, 6), (7, 8), (9, 10)).Seq␤»
    my \m= gather for 1..10 -> $a, $b { take ($a, $b).Slip }; say m.raku;
    # OUTPUT: «(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).Seq␤»

=head1 Methods

=head2 method List

Defined as:

    multi method List(Slip:D: --> List:D)

Turns it into a list.

=head2 sub slip

Defined as:

    multi sub slip(--> Empty)
    multi sub slip(@args --> Slip:D)
    multi sub slip(+args --> Slip:D)

Creates a L<Slip|/type/Slip> from its arguments by calling
L<C<.Slip>|/routine/Slip> on the object formed by them. Returns
L<C<Empty>|/type/Slip#constant_Empty> if called with void arguments.

=head1 Constants

=head2 constant Empty

C<Empty> is a C<Slip> of the empty C<List>.

    say "".comb ~~ Empty;
    # OUTPUT: «True␤»

=end pod


# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
