txt: ## array.md
  class Array
  
  Sequence of itemized values
  
  ```raku
  class Array is List {}
  ```
  
  An `Array` is a [`List`](/type/List) which forces all its elements to be scalar containers, which means you can assign to array elements.
  
  `Array` implements [`Positional`](/type/Positional) and as such provides support for [subscripts](/language/subscripts).
  
  **Note** from version 6.d, `.raku` (`.perl` before version 2019.11) can be called on multi-dimensional arrays.
  
  If you want to declare an `Array` of a specific type, you can do so using several different ways:
  
  ```raku
  my @foo of Int = 33,44;        # [33 44]
  my @bar is Array[Int] = 33,44; # [33 44]
  
  ```
  
  The second example, which parameterizes a type, is only available from Rakudo 2019.03.
  
  # [Methods](#class_Array "go to top of document")[§](#Methods "direct link")
  
  ## [method gist](#class_Array "go to top of document")[§](#method_gist "direct link")
  
  Exactly the same as [`List.gist`](/type/List#method_gist), except using square brackets for surrounding delimiters.
  
  ## [method pop](#class_Array "go to top of document")[§](#method_pop "direct link")
  
  ```raku
  method pop(Array:D:) is nodal
  ```
  
  Removes and returns the last item from the array. Fails if the array is empty.
  
  Like many `Array` methods, method `pop` may be called via the corresponding [subroutine](/type/independent-routines#sub_pop). For example:
  
  ```raku
  my @foo = <a b>; # a b
  @foo.pop;        # b
  pop @foo;        # a
  pop @foo;
  CATCH { default { put .^name, ': ', .Str } };
  # OUTPUT: «X::Cannot::Empty: Cannot pop from an empty Array␤»
  ```
  
  ## [method push](#class_Array "go to top of document")[§](#method_push "direct link")
  
  ```raku
  multi method push(Array:D: **@values is raw --> Array:D)
  multi method push(Array:D: \value --> Array:D)
  multi method push(Array:D: Slip \values --> Array:D)
  ```
  
  Adds the provided value or values to the end of the array, and returns the modified array. If any argument is a [`Slip`](/type/Slip), method `push` will add the values produced by the argument's [iterator](/routine/iterator). It throws if the invocant array or a [`Slip`](/type/Slip) [is lazy](/routine/is-lazy).
  
  Example:
  
  ```raku
  my @foo = <a b c>;
  @foo.push: 'd';
  say @foo;                   # OUTPUT: «[a b c d]␤»
  ```
  
  Note that `push` does not attempt to flatten its argument list. If you pass an array or list as the thing to push, it becomes one additional element:
  
  ```raku
  my @a = <a b c>;
  my @b = <d e f>;
  @a.push: @b;
  say @a.elems;               # OUTPUT: «4␤»
  say @a[3].join;             # OUTPUT: «def␤»
  ```
  
  Multiple values are added to the array only if you supply them as separate arguments or in a [`Slip`](/type/Slip):
  
  ```raku
  my @a = '1';
  say @a.push: 'a', 'b';       # OUTPUT: «[1 a b]␤»
  my @c = <E F>;
  say @a.push: @c.Slip;        # OUTPUT: «[1 a b E F]␤»
  ```
  
  See [method append](/type/Array#method_append) if you want to append multiple values that are produced by a single non-slipping [`Iterable`](/type/Iterable).
  
  ## [method append](#class_Array "go to top of document")[§](#method_append "direct link")
  
  ```raku
  multi method append(Array:D: **@values is raw --> Array:D)
  multi method append(Array:D: \arg --> Array:D)
  ```
  
  Adds the provided values to the end of the array and returns the modified array, or throws if the invocant array or an argument that requires flattening [is lazy](/routine/is-lazy).
  
  In contrast with [method push](/type/Array#method_push), method `append` adheres to the [single argument rule](/language/functions#Slurpy_conventions) and is probably best thought of as:
  
  ```raku
  multi method append(Array:D: +values --> Array:D)
  ```
  
  This means that if you pass a **single** argument that is a non-[itemized](/language/mop#VAR) [`Iterable`](/type/Iterable), `append` will try to flatten it.
  
  For example:
  
  ```raku
  my @a = <a b c>;
  my @b = <d e f>;
  @a.append: @b;
  say @a.elems;               # OUTPUT: «6␤»
  say @a;                     # OUTPUT: «[a b c d e f]␤»
  ```
  
  ## [method elems](#class_Array "go to top of document")[§](#method_elems "direct link")
  
  ```raku
  method elems(Array:D: --> Int:D)
  ```
  
  Returns the number of elements in the invocant. Throws [`X::Cannot::Lazy`](/type/X/Cannot/Lazy) exception if the invocant [is lazy](/routine/is-lazy). For shaped arrays, returns the outer dimension; see [shape](/routine/shape) if you need information for all dimensions.
  
  ```raku
  say [<foo bar ber>] .elems; # OUTPUT: «3␤»
  say (my @a[42;3;70]).elems; # OUTPUT: «42␤»
  
  try [-∞...∞].elems;
  say $!.^name;               # OUTPUT: «X::Cannot::Lazy␤»
  ```
  
  ## [method clone](#class_Array "go to top of document")[§](#method_clone "direct link")
  
  ```raku
  method clone(Array:D: --> Array:D)
  ```
  
  Clones the original `Array`. Modifications of elements in the clone are not propagated to the original and vice-versa:
  
  ```raku
  my @a = <a b c>; my @b = @a.clone;
  @b[1] = 42; @a.push: 72;
  say @b; # OUTPUT: «[a 42 c]␤»
  say @a; # OUTPUT: «[a b c 72]␤»
  ```
  
  However, note that the reifier *is* shared between the two Arrays, so both Arrays will have the same elements even when each is randomly-generated on reification and each element will be reified just once, regardless of whether the reification was done by the clone or the original Array. **Note:** just as reifying an Array from multiple threads is not safe, so is, for example, reifying the clone from one thread while reifying the original from another thread is not safe.
  
  ```raku
  my @a = 1, {rand} … ∞; my @b = @a.clone;
  say @b[^3]; # OUTPUT: «(1 0.0216426755282736 0.567660896142156)␤»
  say @a[^3]; # OUTPUT: «(1 0.0216426755282736 0.567660896142156)␤»
  ```
  
  ## [method flat](#class_Array "go to top of document")[§](#method_flat "direct link")
  
  ```raku
  multi method flat(Array:U:)
  multi method flat(Array:D:)
  ```
  
  This method will return the type object itself if it's applied to a type object; when applied to an object, it will return a [`Seq`](/type/Seq) created from the `Array` underlying iterator.
  
  ```raku
  my @a = <a 2 c>;
  say @a.flat.^name; # OUTPUT: «Seq␤»
  
  ```
  
  ## [method shift](#class_Array "go to top of document")[§](#method_shift "direct link")
  
  ```raku
  method shift(Array:D:) is nodal
  ```
  
  Removes and returns the first item from the array. Fails if the array is empty.
  
  Example:
  
  ```raku
  my @foo = <a b>;
  say @foo.shift;             # OUTPUT: «a␤»
  say @foo.shift;             # OUTPUT: «b␤»
  say @foo.shift;
  CATCH { default { put .^name, ': ', .Str } };
  # OUTPUT: «X::Cannot::Empty: Cannot shift from an empty Array␤»
  ```
  
  ## [routine unshift](#class_Array "go to top of document")[§](#routine_unshift "direct link")
  
  ```raku
  multi        unshift(Array:D, **@values --> Array:D)
  multi method unshift(Array:D: **@values --> Array:D)
  ```
  
  Adds the `@values` to the start of the array, and returns the modified array. Fails if `@values` is a lazy list.
  
  Example:
  
  ```raku
  my @foo = <a b c>;
  @foo.unshift: 1, 3 ... 11;
  say @foo;                   # OUTPUT: «[(1 3 5 7 9 11) a b c]␤»
  ```
  
  The notes in [the documentation for method push](/type/Array#method_push) apply, regarding how many elements are added to the array.
  
  The [routine prepend](/type/Array#routine_prepend) is the equivalent for adding multiple elements from one list or array.
  
  ## [routine prepend](#class_Array "go to top of document")[§](#routine_prepend "direct link")
  
  ```raku
  sub prepend(\array, |values)
  multi method prepend(Array:D: \values)
  multi method prepend(Array:D: **@values is raw)
  ```
  
  Adds the elements from `values` to the front of the array, modifying it in-place.
  
  Example:
  
  ```raku
  my @foo = <a b c>;
  @foo.prepend: 1, 3 ... 11;
  say @foo;                   # OUTPUT: «[1 3 5 7 9 11 a b c]␤»
  ```
  
  The difference from method `unshift` is that if you prepend a **single** array or list argument, `prepend` will flatten that array / list, whereas `unshift` prepends the list / array as just a single element.
  
  ## [routine splice](#class_Array "go to top of document")[§](#routine_splice "direct link")
  
  ```raku
  multi        splice(@list,   $start = 0, $elems?, *@replacement --> Array)
  multi method splice(Array:D: $start = 0, $elems?, *@replacement --> Array)
  ```
  
  Deletes `$elems` elements starting from index `$start` from the `Array`, returns them and replaces them by `@replacement`. If `$elems` is omitted or is larger than the number of elements starting from `$start`, all the elements starting from index `$start` are deleted. If both `$start` and `$elems` are omitted, all elements are deleted from the `Array` and returned.
  
  Each of `$start` and `$elems` can be specified as a [`Whatever`](/type/Whatever) or as a [`Callable`](/type/Callable) that returns an [`Int`](/type/Int)-compatible value: this returned value is then used as the corresponding argument to the `splice` routine.
  
  A [`Whatever`](/type/Whatever) `$start` uses the number of elements of `@list` (or invocant). A [`Callable`](/type/Callable) `$start` is called with one argument—the number of elements in `@list` (or `self`).
  
  A [`Whatever`](/type/Whatever) `$elems` deletes from `$start` to end of `@list` (or `self`) (same as no `$elems`). A [`Callable`](/type/Callable) `$elems` is called with one argument—the number of elements in `@list` (or `self`) minus the value of `$start`.
  
  Example:
  
  ```raku
  my @foo = <a b c d e f g>;
  say @foo.splice(2, 3, <M N O P>);        # OUTPUT: «[c d e]␤»
  say @foo;                                # OUTPUT: «[a b M N O P f g]␤»
  ```
  
  It can be used to extend an array by simply splicing in more elements than the current size (since version 6.d)
  
  ```raku
  my @foo = <a b c d e f g>;
  say @foo.splice(6, 4, <M N O P>);       # OUTPUT: «[g]␤»
  say @foo;                               # OUTPUT: «[a b c d e f M N O P]␤»
  
  ```
  
  The following equivalences hold (assuming that `@a.elems ≥ $i`):
  
  ｢text｣ without highlighting
  
  ```
  
  
  ```
  
  @a.push($x, $y)      @a.splice: *  , *, $x, $y
  @a.pop               @a.splice: *-1,
  @a.shift             @a.splice: 0  , 1,
  @a.unshift($x, $y)   @a.splice: 0  , 0, $x, $y
  @a[$i] = $y          @a.splice: $i , 1, $y,
  
  
  ```
  
  
  ```
  
  As mentioned above, a [`Whatever`](/type/Whatever) or [`Callable`](/type/Callable) object can be provided for both the `$start` and `$elems` parameters. For example, we could use either of them to remove the second to last element from an array provided it's large enough to have one:
  
  ```raku
  my @foo = <a b c d e f g>;
  say @foo.splice: *-2, *-1;           # OUTPUT: «[f]␤»
  say @foo;                            # OUTPUT: «[a b c d e g]␤»
  
  my &start     = -> $n { $n - 2 };
  my &elems-num = -> $m { $m - 1 };
  say @foo.splice: &start, &elems-num; # OUTPUT: «[e]␤»
  say @foo;                            # OUTPUT: «[a b c d g]␤»
  ```
  
  ## [method shape](#class_Array "go to top of document")[§](#method_shape "direct link")
  
  ```raku
  method shape() { (*,) }
  ```
  
  Returns the shape of the array as a list.
  
  Example:
  
  ```raku
  my @foo[2;3] = ( < 1 2 3 >, < 4 5 6 > ); # Array with fixed dimensions
  say @foo.shape;                          # OUTPUT: «(2 3)␤»
  my @bar = ( < 1 2 3 >, < 4 5 6 > );      # Normal array (of arrays)
  say @bar.shape;                          # OUTPUT: «(*)␤»
  ```
  
  ## [method default](#class_Array "go to top of document")[§](#method_default "direct link")
  
  ```raku
  method default
  ```
  
  Returns the default value of the invocant, i.e. the value which is returned when trying to access an element in the `Array` which has not been previously initialized or when accessing an element which has explicitly been set to [`Nil`](/type/Nil). Unless the `Array` is declared as having a default value by using the [is default](/type/Variable#trait_is_default) trait the method returns the type object for [`Any`](/type/Any).
  
  ```raku
  my @a1 = 1, "two", 2.718;
  say @a1.default;                               # OUTPUT: «(Any)␤»
  say @a1[4];                                    # OUTPUT: «(Any)␤»
  
  my @a2 is default(17) = 1, "two", 3;
  say @a2.default;                               # OUTPUT: «17␤»
  say @a2[4];                                    # OUTPUT: «17␤»
  @a2[1] = Nil;                                  # (resets element to its default)
  say @a2[1];                                    # OUTPUT: «17␤»
  
  ```
  
  ## [method of](#class_Array "go to top of document")[§](#method_of "direct link")
  
  ```raku
  method of()
  ```
  
  Returns the type constraint for the values of the invocant. By default, i.e. if no type constraint is given during declaration, the method returns `(Mu)`.
  
  ```raku
  my @a1 = 1, 'two', 3.14159;              # (no type constraint specified)
  say @a1.of;                              # OUTPUT: «(Mu)␤»
  
  my Int @a2 = 1, 2, 3;                    # (values must be of type Int)
  say @a2.of;                              # OUTPUT: «(Int)␤»
  @a2.push: 'd';
  CATCH { default { put .^name, ': ', .Str } };
  # OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to @a2; expected Int but got Str ("d")␤»
  ```
  
  ## [method dynamic](#class_Array "go to top of document")[§](#method_dynamic "direct link")
  
  ```raku
  method dynamic(Array:D: --> Bool:D)
  ```
  
  Returns `True` if the invocant has been declared with the [is dynamic](/routine/is dynamic) trait, that is, if it's a dynamic variable that can be accessed from the inner lexical scope without having been declared there.
  
  ```raku
  my @a;
  say @a.dynamic;                          # OUTPUT: «False␤»
  
  my @b is dynamic;
  say @b.dynamic;                          # OUTPUT: «True␤»
  ```
  
  If you declare a variable with the `*` twigil `is dynamic` is implied.
  
  ```raku
  my @*b;
  say @*b.dynamic;                         # OUTPUT: «True␤»
  ```
  
  Please note that the `dynamic` trait is a property of the variable, not the content. If a [`Scalar`](/type/Scalar) dynamic variable contains an array, rules for this container will apply (and it will always return `False`).
  
  ## [method List](#class_Array "go to top of document")[§](#method_List "direct link")
  
  ```raku
  multi method List(Array:D:)
  ```
  
  Converts the array to a [`List`](/type/List).
  
  ```raku
  my @array= [1];
  @array[3]=3;
  say @array.List;       # OUTPUT: «(1 Nil Nil 3)␤»
  
  ```
  
  The holes will show up as [`Nil`](/type/Nil).
  
  ## [method Slip](#class_Array "go to top of document")[§](#method_Slip "direct link")
  
  ```raku
  multi method Slip(Array:D: --> Slip:D)
  ```
  
  Converts the array to a [`Slip`](/type/Slip), filling the holes with the type value the `Array` has been defined with.
  
  ```raku
  my Int @array= [0];
  @array[3]=3;
  say @array.Slip; # OUTPUT: «(0 (Int) (Int) 3)␤»
  
  ```
  
  # [Typegraph](# "go to top of document")[§](#typegraphrelations "direct link")
  
  Type relations for `Array`
  
  
  
  raku-type-graph
  
  
  
  Array
  Array
  
  
  List
  List
  
  
  Array->List
  
  
  
  Mu
  Mu
  
  
  Any
  Any
  
  
  Any->Mu
  
  
  
  Cool
  Cool
  
  
  Cool->Any
  
  
  
  Positional
  Positional
  
  
  Iterable
  Iterable
  
  
  List->Cool
  
  
  
  List->Positional
  
  
  
  List->Iterable
  
  [Expand chart above](/assets/typegraphs/Array.svg)
  