txt: ## seq.md
  class Seq
  
  An iterable, potentially lazy sequence of values
  
  ```raku
  class Seq is Cool does Iterable does Sequence { }
  ```
  
  A `Seq` represents anything that can produce a sequence of values. A `Seq` is born in a state where iterating it will consume the values. Calling `.cache` on a `Seq` will make it store the generated values for later access.
  
  A high-level construct to generate a `Seq` is [`gather/take`](/syntax/gather%20take), as well as many built-in methods like [`map`](/routine/map) and [`grep`](/routine/grep), low-level constructors to create a `Seq` from an iterator or from looping constructs are available too.
  
  A `Seq` can also be constructed with the [sequence operator `...`](/language/operators#infix_...) or one of its variants.
  
  ```raku
  my $s = (1...5);
  say $s;              # OUTPUT: «(1 2 3 4 5)␤»
  say $s.^name;        # OUTPUT: «Seq␤»
  ```
  
  Assigning the values of a `Seq` to an array consumes a `Seq` that is not lazy. Use the `lazy` statement prefix to avoid a `Seq` from being iterated during the assignment:
  
  ```raku
  # The Seq created by gather ... take is consumed on the spot here.
  my @a = gather do { say 'consuming...'; take 'one' };  # OUTPUT: «consuming...␤»
  
  # The Seq here is only consumed as we iterate over @a later.
  my @a = lazy gather do { say 'consuming...'; take 'one' };  # outputs nothing.
  .say for @a;  # OUTPUT: «consuming...␤one␤»
  
  ```
  
  A typical use case is [method `lines` in `IO::Handle`](/type/IO/Handle#routine_lines), which could use a lot of memory if it stored all the lines read from the file. So
  
  ```raku
  for open('README.md').lines -> $line {
      say $line;
  }
  
  ```
  
  won't keep all lines from the file in memory.
  
  This implies that you cannot iterate the same `Seq` object twice (otherwise it couldn't throw away old values), so this dies:
  
  ```raku
  my @a = 1, 2, 3;
  my @b = <a b c>;
  my \c = @a Z=> @b;
  .say for c;
  .say for c; # fails
  CATCH { default { put .^name, ': ', .Str } };
  # OUTPUT: «X::Seq::Consumed: This Seq has already been iterated, and its values consumed
  # (you might solve this by adding .cache on usages of the Seq, or
  # by assigning the Seq into an array)»
  ```
  
  **Caution:** No program should ever assume a `Seq` may only be iterated once even if not cached by the program. Caching is a volatile state exposed to the developer as an optimization. The `Seq` may become cached by many operations, including calling `.raku` (`.perl` before version 2019.11) on the `Seq` (if called prior to a non-cached iteration). From version 6.d, `.raku` (again, `.perl` before version 2019.11) can be called on consumed `Seq`. If a program assumes a `Seq` can only iterate once, but then is later changed to call one of these operations during the loop, that assumption will fail.
  
  On a cached `Seq`, the cached list is used when `&infix:<eqv>`, `.Slip`, `.join`, `.List`, `.list`, `.eager`, `.Array` and `.is-lazy` are called.
  
  You can smartmatch a regex with `Seq`, even if it's infinite
  
  ```raku
  my @fib = 1,1, *+* ... *;
  say @fib[^1000] ~~ /^9999/; # OUTPUT: «Nil␤»
  ```
  
  However, infinite or lazy `Seq` will be vivified when doing the match, leading to possibly infinite loops, so be sure to limit search somehow.
  
  # [Methods](#class_Seq "go to top of document")[§](#Methods "direct link")
  
  ## [method new](#class_Seq "go to top of document")[§](#method_new "direct link")
  
  ```raku
  proto method new(Seq: |) {*}
  multi method new(Seq: Iterator:D $iter)
  multi method new(Seq:)
  
  ```
  
  Creates a new `Seq` object from the supplied iterator passed as the single argument. Creates an empty `Seq` if called with no argument.
  
  ## [method iterator](#class_Seq "go to top of document")[§](#method_iterator "direct link")
  
  ```raku
  method iterator(Seq:D:)
  ```
  
  If the `Seq` is not cached, returns the underlying iterator and marks the invocant as consumed. If called on an already consumed sequence, throws an error of type [`X::Seq::Consumed`](/type/X/Seq/Consumed).
  
  Otherwise returns an iterator over the cached list.
  
  ## [method is-lazy](#class_Seq "go to top of document")[§](#method_is-lazy "direct link")
  
  ```raku
  method is-lazy(Seq:D:)
  ```
  
  Returns `True` if and only if the underlying iterator or cached list considers itself lazy. If called on an already consumed sequence, throws an error of type [`X::Seq::Consumed`](/type/X/Seq/Consumed).
  
  ## [method Seq](#class_Seq "go to top of document")[§](#method_Seq "direct link")
  
  ```raku
  multi method Seq(Seq:D:)
  ```
  
  Clones the object.
  
  ## [method Capture](#class_Seq "go to top of document")[§](#method_Capture "direct link")
  
  ```raku
  method Capture()
  ```
  
  Coerces the object to a [`List`](/type/List), which is in turn coerced into a [`Capture`](/type/Capture).
  
  ## [method elems](#class_Seq "go to top of document")[§](#method_elems "direct link")
  
  ```raku
  method elems(Seq:D:)
  ```
  
  Returns the number of values in the sequence. If this number cannot be predicted, the `Seq` is cached and evaluated till the end.
  
  Because an infinite sequence cannot be evaluated till the end, such a sequence *should* be declared lazy. Calling `.elems` on a lazy `Seq` [fail](/routine/fail)s with [`X::Cannot::Lazy`](/type/X/Cannot/Lazy).
  
  ## [method from-loop](#class_Seq "go to top of document")[§](#method_from-loop "direct link")
  
  ```raku
  multi method from-loop(&body, :$label)
  multi method from-loop(&body, &cond, :$repeat!, :$label)
  multi method from-loop(&body, &cond, :$label)
  multi method from-loop(&body, &cond, &afterwards, :$label)
  ```
  
  These methods create new `Seq`-based callbacks.
  
  In general, it produces an infinite `Seq` by calling `&body` each time a new element is requested, using the return value from `&body` as the item. This emulates (or implements) a `loop { body }` construct.
  
  When the multi includes `&cond`, it's invoked before each call to `&body`, and terminates the sequence if `&cond` returns a false value. If `$repeat` is set to a true value, the first call to `&cond` is omitted, and `&body` called right away. This emulates (or implements) `while cond { body }` and `repeat { body } while cond` loops.
  
  If present, `&afterward` will be called after each call to `&body`.
  
  ## [method sink](#class_Seq "go to top of document")[§](#method_sink "direct link")
  
  ```raku
  method sink(--> Nil)
  ```
  
  Calls [`sink-all`](/routine/sink-all) if it is an [`Iterator`](/type/Iterator), `sink` if the Sequence is a list.
  
  ```raku
  say (1 ... 1000).sink; # OUTPUT: «Nil␤»
  ```
  
  This is something you might want to do for the side effects of producing those values.
  
  ## [method skip](#class_Seq "go to top of document")[§](#method_skip "direct link")
  
  ```raku
  multi method skip(Seq:D:)
  multi method skip(Seq:D: Whatever)
  multi method skip(Seq:D: Callable:D $w)
  multi method skip(Seq:D: Int() $n)
  multi method skip(Seq:D: $skip, $produce)
  ```
  
  Returns a Seq containing whatever is left of the invocant after throwing away `$n` of the next available values. Negative values of `$n` count as 0. Also can take a [`WhateverCode`](/type/WhateverCode) to indicate how many values to skip from the end. Will block on lazy Seqs until the requested number of values have been discarded.
  
  ```raku
  say (1..5).Seq.skip;      # OUTPUT: «(2 3 4 5)␤»
  say (1..5).Seq.skip(3);   # OUTPUT: «(4 5)␤»
  say (1..5).Seq.skip(5);   # OUTPUT: «()␤»
  say (1..5).Seq.skip(-1);  # OUTPUT: «(1 2 3 4 5)␤»
  ```
  
  Calling it with [`Whatever`](/type/Whatever) will return an empty `Seq`:
  
  ```raku
  say <1 2 3>.Seq.skip(*);  # OUTPUT: «()␤»
  ```
  
  The multi that uses a Callable is intended mainly to be used this way:
  
  ```raku
  say (1..5).Seq.skip(*-3); # OUTPUT: «(3 4 5)␤»
  ```
  
  Instead of throwing away the first `$n` elements, it throws away everything *but* the elements indicated by the WhateverCode, in this case all but the last three elements.
  
  As of language version `6.e` (early implementation exists in Rakudo compiler 2022.12+), it is also possible to specify multiple argument values. These are then interpreted as number of values to produce, then skip, then produce, etc.
  
  ```raku
  say (1..12).Seq.skip(2,3,4); # OUTPUT: «(3 4 5 10 11 12)␤»
  ```
  
  This first skipped 2 values, then produced 3 values (3, 4, 5), skipped 4 values and then produced the rest (10, 11, 12).
  
  If the final value specified is in a "produce" position, then the rest of the `Seq` will be skipped. If the final value is in a "skip" position, then the rest of the `Seq` will be produced.
  
  ```raku
  say (1..10).Seq.skip(2,3,1,2); # OUTPUT: «(3 4 5 7 8)␤»
  say (1..10).Seq.skip(2,3,1);   # OUTPUT: «(3 4 5 7 8 9 10)␤»
  ```
  
  If a [`Whatever`](/type/Whatever) is specified in a "produce" position, it will cause the rest of the `Seq` to be produced. Otherwise, it will cause the rest if the `Seq` to be skipped.
  
  ```raku
  say (1..10).Seq.skip(2,*);   # OUTPUT: «(3 4 5 6 7 8 9 10)␤»
  say (1..10).Seq.skip(2,3,*); # OUTPUT: «(3 4 5)␤»
  ```
  
  If you want to start with producing values instead of skipping, specify **0** as the first value.
  
  ```raku
  say (1..10).Seq.skip(0,3,4); # OUTPUT: «(1 2 3 8 9 10)␤»
  ```
  
  If you want an unending repeating pattern of skips and produces, you can specify the arguments as an unending `Seq` themselves.
  
  ```raku
  say (^20).Seq.skip(|(2,3) xx *); # OUTPUT: «(0 1 5 6 10 11 15 16)␤»
  ```
  
  ## [multi method slice](#class_Seq "go to top of document")[§](#multi_method_slice "direct link")
  
  ```raku
  method slice(Seq:D: *@indices --> Seq:D)
  ```
  
  Available as of the 2021.02 release of the Rakudo compiler.
  
  The `slice` method takes a number of monotonically increasing indices for which to produce the value from the invocant in a new `Seq`. Indices can be single numbers or ranges, as long they are increasing in value.
  
  This provides a more efficient way of getting specific values out of a `Seq` than either caching the `Seq` or converting it to a [`List`](/type/List) or [`Array`](/type/Array).
  
  ```raku
  say (1..10).Seq.slice(0, 3..6, 8);  # OUTPUT: «(1 4 5 6 7 9)␤»
  ```
  
  # [Typegraph](# "go to top of document")[§](#typegraphrelations "direct link")
  
  Type relations for `Seq`
  
  
  
  raku-type-graph
  
  
  
  Seq
  Seq
  
  
  Cool
  Cool
  
  
  Seq->Cool
  
  
  
  Iterable
  Iterable
  
  
  Seq->Iterable
  
  
  
  Sequence
  Sequence
  
  
  Seq->Sequence
  
  
  
  Mu
  Mu
  
  
  Any
  Any
  
  
  Any->Mu
  
  
  
  Cool->Any
  
  
  
  PositionalBindFailover
  PositionalBindFailover
  
  
  Sequence->PositionalBindFailover
  
  [Expand chart above](/assets/typegraphs/Seq.svg)
  