Scalar, sigil: $

    list $foo        # $foo
        +$foo        # $foo as Num
        ~$foo        # $foo as Str
        ?$foo        # $foo as Bool
        "$foo"       # $foo as Str
    item $foo        # $foo

Scalar -> Str

    Methods:

    .chomp    # Returns chomped string with a .newline property giving the
                newline removed
    .chop
    .ord
    .lc
    .lcfirst
    .uc
    .ucfirst
    .chars    # Length in characters
    .graphs   # Length in graphemes
    .codes    # Length in codepoints
    .bytes    # Length in bytes
    .tr
    .reverse
    .split(/sep/)
    .hex
    .oct

Scalar -> Num

    .abs
    .cos
    .exp
    .int
    .log
    .rand
    .sin
    .sqrt
    .chr
    .floor
    .ceil
    
Array, sigil: @
    
    list @foo        # List of elements
        +@foo        # @foo.elems
        ~@foo        # join ' ', @foo
        ?@foo        # ? @foo.elems
        "@foo[]"     # join ' ', @foo
         @foo[i]     # subscript
         @foo[i, i]  # slice
         @foo[i; i]  # multi-dimensional access
    item @foo        # \@foo

    Methods:

    .elems          # Number of elements
    .join($sep)
    .map:{ ... }
    .grep:{ ... }
    .pop
    .push($elem)
    .shift
    .unshift($elem)
    .reverse
    .sort( { cond }, { cond }, ... )
    .kv            # return index,value pairs
    
    Shapes:

    XXX - someone summarize shapes and multi-dimension syntax

    Constructors:

    ARRAY = LIST
    [ LIST ]       # anonymous ref

    Note:
        (42)       # this is neither a list nor an array,
                   # but a scalar (the Num 42)
        (42,)      # this is an one-element array
        list 42    # this is an one-element array
        (42,23)    # this is a two-element array

        []         # this is a zero-element arrayref
        [42]       # this is an one-element arrayref
        [42,]      # this is an one-element arrayref
        [42,23]    # this is a two-element arrayref

    List construction (via the comma operator, &infix:<,>), does not create
    containers, meaning that the elements are aliases:

        ($foo,$bar)[0] =:= $foo;  # true
        ($foo,$bar)[0]   = $baz;  # $foo changed to $baz

    This also means that

        (42,23)[0] = 17;  # is a fatal error ("can't modify constant")
        # Similarly, you can't shift(), pop(), unshift() etc. arrays created by
        # the comma operator:
        shift (42,23);    # dies

    By contast, arrayref construction by the [] operator, &circumfix:<[ ]>,
    does create new containers:

        [$foo,$bar][0] =:= $foo;  # false
        [$foo,$bar][0]   = $baz;  # $foo not changed

        shift [42,23];            # lives (but the arrayref is discarded after
                                  # the operation)

        my @array = (42,23);
        shift @array;             # works too, as assignment to an array
                                  # implicitly creates new containers.

    (While in Perl 5 the distinction between lists and arrays was necessary and
    very useful, this distinction is very much blurred in Perl 6. Amongst other
    reasons, this is because arrays auto-reference in scalar context to a
    reference to itself. Also, it's no longer the parentheses which create list
    context, but a slurpy array in some signature. In Perl 6, the comma
    operator creates arrays, parens are only for grouping:

        # Perl 5
        sub foo { (1,2,3) }
        my $scalar = foo();  # 3
        my @array  = foo();  # (1,2,3)

        # Perl 6
        sub foo { (1,2,3) }
        my $scalar = foo();  # [1,2,3]
        my @array  = foo();  # (1,2,2)

    Also note that list context, i.e. the context supplied by a slurpy array in
    a signature, automatically flattens arrays and hashes (but not references
    to arrays or hashes):

        sub this_provides_list_context (*@things) { @things[0] }
        my @foo = <a b c>;
        my @bar = <d e f>;
        say this_provides_list_context(@foo, @bar);
        # "a", not the stringification of @foo (which would be "a b c").

    The list constructing comma operator supplies this list context:

        sub *infix:<,> (*@things) {...}

    This also explains why (@foo, @bar) does not create an array containing two
    elements, but an array containing @foo+@bar items. (Like
    "@foo.concat(@bar)" in other languages.))

Hash, sigil: %

    list %foo        # List of pairs
        +%foo        # +%foo.keys
        ~%foo        # ???
        ?%foo        # ? %foo.keys
        "%foo{}"     # ???
         %foo{k}     # subscript
         %foo{k, k}  # slice
         %foo<>      # %foo{<>}
         %foo<<>>    # %foo{<<>>}
         %foo{k; k}  # multi-dimensional access
    item %foo        # \%foo

    Methods:

    .delete($key)
    .exists($key)
    .keys
    .values
    .kv                # List of key, value, key, value, ...

    Shapes: 

    XXX - help me

    Constructors:

    HASH = LIST
    { PAIR, PAIR, ... }   # anonymous ref
    hash( LIST )

Pair (used via reference)

    list $foo        # $foo   # ref, so doesn't flatten to $k, $v
        +$foo        # ???
        ~$foo        # ???
        ?$foo        # ???
        "$foo"       # ???
    item $foo        # $foo

    Methods:

    .kv      # $key, $value
    .key
    .value
    
    Constructors: (all anonymous)

    :key            # 'key' => 1
    :key{'value'}   # 'key' => 'value'
    \__ thus: :key<>, :key<<>>
    key => 'value'  # 'key' => 'value' (LHS auto-quoted)

References

    In Perl 6, references usually auto-dereference when treated
    non-referentially. This auto-referentiation magic applies to references to
    arrays and hashes:

        my $arrayref = @array;     # sugar for
        my $arrayref = \@array;
        say $arrayref[42];         # outputs @array[42]
        say $arrayref ~~ Ref;      # false
        say $arrayref ~~ Array;    # true

        my $hashref = %hash;       # sugar for
        my $hashref = \%hash;
        say $hashref<key>;         # outputs %hash<key>
        say $hashref ~~ Ref;       # false
        say $hashref ~~ Hash;      # true

    References to other things do not automatically dereference:

        my $scalarref = \42;
        say ~$scalarref;           # dies ("can't stringify references")
        say +$scalarref;           # dies ("can't numify references")
        say ?$scalarref;           # true, even if $scalarref happened to
                                   # point to an otherwise false value
                                   # (e.g. undef or 0).
        say $scalarref ~~ Ref;     # true
        say $scalarref ~~ Num;     # false

        my $scalarref = \\@array;  # reference to a reference to an array
        say $scalarref ~~ Ref;     # true
        say $scalarref ~~ Array;   # false

    The auto-dereferentiation magic does only apply to numification,
    stringification, and booleanification, *not* to assignment and binding.

        my $foo  = @array;
        my $bar  = $foo;
        $bar[42] = $new;           # @array[42] changed to $new

    References (even references to arrays or hashes) do not flatten in list
    context:

        my @array = ($arrayref1, $arrayref2);
        # @array consists of two elements

    (Also note that

        my @array = $arrayref;     # is sugar for
        my @array = ($arrayref,);  # which means that
        say +@array;               # will output 1.)

Things with blocks

    Named               Anonymous             See also
    class   Foo { }     class   { }           oo
    role    Foo { }     role    { }           oo
    sub     foo { }     sub     { }, or { }   sub
    method  foo { }     method  { }           oo, sub
    macro   foo { }                           sub
    rule    foo { }     rule    { }           rules
    grammar Foo { }     grammar { }           rules
    package Foo { }     package { }           mod
    module  Foo { }     module  { }           mod

Variable names, containers, values, etc.

    A variable name is '$foo', '@foo', '%foo', etc.

    In the symbol table/the lexical pad, links from variable names to
    their containers are stored.
    
    A variable with ... sigil always points to a ... container:
      $  -->  Scalar
      @  -->  Array
      %  -->  Hash
      &  -->  Scalar
      ^  -->  Scalar

    A scalar container holds a single cell. This cell can either be constant or
    modifiable. Binding replaces the cell.
      $a := $b;  # $a's cell slot points to $b's cell.
      $b := $c;  # $b's cell slot points to $c's cell.
                 # $a's cell slot still points to what used to be $b's cell.

    Array and hash containers hold many cells. Again, binding replaces a cell.
      @array[$idx] := $b;  # @array's cell slot number $idx points to $b's
                           # cell.
      $b := $c;            # $b's cell slot points to $c's sell.
                           # @array's cell slot number $idx still points to
                           # what used to be $b's cell.

    Cells hold the actual values, for example the Num 3 or the Str "Pugs".

    To summarize:
      '$foo' entry in the lexical pad points to...
      the container of '$foo'. The container holds...
      a cell, which in turn holds...
      $foo's value.

    Examples:

      $foo = 42;
      # '$foo' --> $foo's container --> cell 123 --> Num 42

      $bar = \$foo;
      # '$bar' --> $bar's container --> cell 456 --> Ref -->
               --> $foo's container --> cell 123 --> Num 42

      $grtz = 23;
      @array = ($foo, $grtz)
      # '@array' --> @array's container -->
      #          --> [
      #                 0 --> cell 111 --> Num 42,
      #                 1 --> cell 222 --> Num 23,
      #              ]
      # (Changing $foo or $grtz does not have an effect on @array yet.)

      @array[0] := $foo;
      # '@array' --> @array's container -->
      #          --> [
      #                 0 --> cell 123 --> Num 42,
      #                 1 --> cell 222 --> Num 23,
      #              ]
      # (Changing $grtz still does not have an effect on @array. Changing $foo
      # (by assignment) does have an effect on @array. Rebinding $foo to some
      # other variable causes further assignments to $foo to have no effect on
      # @array again.)

    =:= tests whether the cell slots of two containers $a and $b point to the
    same cell.

      $a = 42;
      # '$a' --> $a's container --> cell 42 --> Num 42

      $b = 42;
      # '$b' --> $b's container --> cell 23 --> Num 42
      $a =:= $b;  # false, of course

      $b := $a;
      # '$b' --> $b's container --> cell 42 --> Num 42

    === (formerly eqv) tests whether the values of two cells are identical.

      42 === 42;  # true

      my $a = 42;
      my $b = 42;
      $a =:= $b;  # false, of course
      $a === $b;  # true

    Method calls always go to the container of a variable, but Scalar (the
    container class of scalar variables) can be thought of as providing an
    appropriate AUTOMETH which redirects most calls to the cell of a container.
    Method calls on arrays and hashes always go the container (of course).

      $dog.bark();   # method call first dispatched to $dog's container,
                     # then redispatched to $dog's value, i.e. a Dog object.
      @array.elems;  # method call dispatched to @array's container.

    An example of a method on scalar variables which is not redirected to the
    cell is .exists. .exists on scalar containers test, whether the
    container's cell slot is not empty. Example:

      sub foo ($a?) { $a.exists }
      foo();    # false
      foo(42);  # true

    (.exists on array and hash containers test whether an element of a given
    index/name exists:

      my @array = (1,2,3);
      @array.exists(1);   # true (@array[1] is 2)
      @array.exists(3);   # false

      my %hash = (a => 1, b => 2);
      %hash.exists("a");  # true (%hash<a> is 1)
      %hash.exists("c");  # false)

    (Reading t/operators/binding/*, t/operators/identity.t, and
    t/operators/value_equivalence.t is strongly recommended.)
