txt: ## contexts.md
  Contexts and contextualizers
  
  What are contexts and how to switch into them
  
  Contexts interpret the value of a container. In Raku, we use the active context to coerce the value of a container into a type or class, or to decide what to do with it. Usually, a context receiving an object will, if necessary, coerce the object by implicitly calling a specific method on it.
  
  # [Sink](#Contexts_and_contextualizers "go to top of document")[§](#Sink "direct link")
  
  The *sink* context is equivalent to what other languages call `void` context. It is the context which does nothing with the result or return of any code: a term, an operation or a block. In general, when this context consumes a value or variable a warning or error is issued because the value is being ignored. Mnemonics for *sink* relate to being rid of something: water down a sink's drain; a ship sinking; a heatsink removing warmth.
  
  ```raku
  my $sub = -> $a { $a² };
  $sub; # OUTPUT: «WARNINGS:␤Useless use of $sub in sink context (line 1)␤»
  
  ```
  
  You can force that sink context on [`Iterator`](/type/Iterator)s, by using the [`sink-all`](/routine/sink-all) method. [`Proc`](/type/Proc)s can also be [sunk via the `sink` method](/type/Proc#method_sink), forcing them to raise an exception and not return anything.
  
  Most blocks will warn if evaluated in sink context; however, [gather/take blocks](/language/control#gather/take) are explicitly evaluated in sink context, with values returned explicitly using `take`:
  
  ```raku
  my @results = gather for 1..1 { ^10 .map: *.take };
  say @results; # OUTPUT: «[0 1 2 3 4 5 6 7 8 9]␤»
  
  ```
  
  In this example, `for` is run in sink context, and within it, `map` is too. Results are taken explicitly from the loop via gather/take.
  
  In sink context, an object will call its `sink` method if present:
  
  ```raku
  sub foo {
      return [<a b c>] does role {
          method sink { say "sink called" }
      }
  }
  foo; # OUTPUT: «sink called␤»
  
  ```
  
  # [Number](#Contexts_and_contextualizers "go to top of document")[§](#Number "direct link")
  
  This context, and probably all other contexts except *sink* above, are *conversion* or *interpretation* contexts in the sense that they take an untyped or typed variable and duck-type it to whatever is needed to perform the operation. In some cases that will imply a conversion (from [`Str`](/type/Str) to [`Numeric`](/type/Numeric), for instance); in other cases simply an interpretation ([`IntStr`](/type/IntStr) will be interpreted as [`Int`](/type/Int) or as [`Str`](/type/Str)).
  
  *Number context* is called whenever we need to apply a numerical operation on a variable.
  
  ```raku
  my $stringone = "1                 ";
  my $stringthree = "3                        ";
  say $stringone + $stringthree; # OUTPUT: «4␤»
  
  ```
  
  In the code above, strings will be interpreted in numeric context as long as there are only a few digits and no other characters. It can have any number of leading or trailing whitespace, however.
  
  Numeric context can be forced by using arithmetic operators such as `+` or `-`. In that context, the [`Numeric`](/routine/Numeric) method will be called if available and the value returned used as the numeric value of the object.
  
  ```raku
  my $t = True;
  my $f = False;
  say $t + $f;      # OUTPUT: «1␤»
  say $t.Numeric;   # OUTPUT: «1␤»
  say $f.Numeric;   # OUTPUT: «0␤»
  my $list= <a b c>;
  say True + $list; # OUTPUT: «4␤»
  say +"  \n ";     # OUTPUT: «0␤»
  
  ```
  
  Whitespace in any quantity will be converted to 0, as is shown in the last statement. In the case of *listy* things, the numeric value will be in general equivalent to `.elems`; in some cases, like [`Thread.numeric`](/routine/Numeric#(Thread)_method_Numeric), it will return a unique thread identifier.
  
  # [String](#Contexts_and_contextualizers "go to top of document")[§](#String "direct link")
  
  In a *string context*, values can be manipulated as strings. This context is used, for instance, for coercing non-string values so that they can be printed to standard output.
  
  ```raku
  put $very-complicated-and-hairy-object; # OUTPUT: something meaningful
  
  ```
  
  Or when smartmatching to a regular expression:
  
  ```raku
  put 333444777 ~~ /(3+)/; # OUTPUT: «333␤»
  ```
  
  In general, the [`Str` routine](/routine/Str) will be called on a variable to contextualize it; since this method is inherited from [`Mu`](/type/Mu), it is always present, but it is not always guaranteed to work. In some core classes it will issue a warning.
  
  [`~`](/routine/~) is the (unary) string contextualizer. As an operator, it concatenates strings, but as a prefix operator it becomes the string context operator.
  
  ```raku
  my @array = [ [1,2,3], [4,5,6]];
  say ~@array; # OUTPUT: «1 2 3 4 5 6␤»
  
  ```
  
  This will happen also in a [*reduction*](/language/operators#Reduction_operators) context, when `[~]` is applied to a list
  
  ```raku
  say [~] [ 3, 5+6i, Set(<a b c>), [1,2,3] ]; # OUTPUT: «35+6ic a b1 2 3␤»
  ```
  
  In that sense, empty lists or other containers will stringify to an empty string:
  
  ```raku
  say [~] [] ; # OUTPUT: «␤»
  ```
  
  Since [`~` acts also as buffer concatenation operator](/routine/~#(Operators)_infix_~), it will have to check that every element is not empty, since a single empty buffer in string context will behave as a string, thus yielding an error.
  
  ```raku
  say [~] Buf.new(0x3,0x33), Buf.new(0x2,0x22);
  # OUTPUT: «Buf:0x<03 33 02 22>␤»
  ```
  
  However,
  
  ```raku
  my $non-empty = Buf.new(0x3, 0x33);
  my $empty = [];
  my $non-empty-also = Buf.new(0x2,0x22);
  say [~] $non-empty, $empty, $non-empty-also;
  # OUTPUT: «Cannot use a Buf as a string, but you called the Stringy method on it
  
  ```
  
  Since `~` is putting in string context the second element of this list, [`~`](/routine/~#(Operators)_infix_~) is going to be using the second form that applies to strings, thus yielding the shown error. Simply making sure that everything you concatenate is a buffer will avoid this problem.
  
  ```raku
  my $non-empty = Buf.new(0x3, 0x33);
  my $empty = Buf.new();
  my $non-empty-also = Buf.new(0x2,0x22);
  say [~] $non-empty, $empty, $non-empty-also; # OUTPUT: «Buf:0x<03 33 02 22>␤»
  
  ```
  
  In general, a context will coerce a variable to a particular type by calling the contextualizer; in the case of mixins, if the context class is mixed in, it will behave in that way.
  
  ```raku
  my $described-number = 1i but 'Unity in complex plane';
  put $described-number; # OUTPUT: «Unity in complex plane␤»
  ```
  
  `but` creates a mixin, which endows the complex number with a [`Str`](/type/Str) method. `put` contextualizes it into a string, that is, it calls [`Str`](/type/Str), the string contextualizer, with the result shown above.
  
  # [Boolean](#Contexts_and_contextualizers "go to top of document")[§](#Boolean "direct link")
  
  This context will force a variable to be interpreted as `True` or `False`.
  
  ```raku
  say "Hey" if 7;  # OUTPUT: «Hey␤»
  say "Ahoy" if "";
  ```
  
  This context appears in expressions such as `if` or `while`, and is equivalent to calling `so` on these values.
  
  ```raku
  say "Hey" if 7.so;          # OUTPUT: «Hey␤»
  say "Ahoy" if not set().so; # OUTPUT: «Ahoy␤»
  
  ```
  
  In general, non-zero, non-empty will be converted to `True`; zero or empty will be equivalent to `False`. But `.so` can be defined to return any Boolean value we want, so this is just a rule of thumb.
  
  The [`?`](/language/operators#prefix_?) Boolean context operator and the [`!`](/language/operators#prefix_!) negated Boolean context operator will force the Boolean context on an object.
  
  ```raku
  say ? 0i;    # OUTPUT: «False␤»
  say ! :true; # OUTPUT: «False␤»
  
  ```
  
  # [List](#Contexts_and_contextualizers "go to top of document")[§](#List "direct link")
  
  There are actually several different [list contexts](/language/list#List_contexts), which are better explained in that page. In general, the list contextualizer is the comma `,`
  
  ```raku
  say (3,).^name; # OUTPUT: «List␤»
  ```
  
  and the method called in that case is also `.list`
  
  ```raku
  Any.list.^name;   # OUTPUT: «List␤»
  say 3.list.^name; # OUTPUT: «List␤»
  say (^3).list;    # OUTPUT: «(0 1 2)␤»
  
  ```
  
  # [Item context](#Contexts_and_contextualizers "go to top of document")[§](#Item_context "direct link")
  
  Item or scalar context will deal with complex pieces of data as if they were a single item. It is forced when you try to assign to a scalar variable
  
  ```raku
  my $scalar-context = <1 2 3>;
  say "→ $_" for $scalar-context; # OUTPUT: «→ 1 2 3␤»
  
  ```
  
  It can be induced using the `$` operator, that acts as the contextualizer operator by calling `item` as a method or routine
  
  ```raku
  .say for $(1,2,3);      # OUTPUT: «(1 2 3)␤»
  .say for (1,2,3).item;  # OUTPUT: «(1 2 3)␤»
  .say for item( 1..3 );  # OUTPUT: «1..3␤»
  
  ```
  
  Itemization affects only their behavior in list context; however, they will still keep their [`Positional`](/type/Positional) role or other roles they might have:
  
  ```raku
  $(1,2,3).elems.say;          # OUTPUT: «3␤»
  say (1,2,3).item[2];         # OUTPUT: «3␤»
  say $( key => 'value')<key>; # OUTPUT: «value␤»
  
  ```
  
  Itemization *containerizes* values in a data structure keeping them, for instance, from being flattened into the surrounding list or data structure:
  
  ```raku
  .say for (1, $(2,3), 4).flat; # OUTPUT: «1␤(2 3)␤4␤»
  say (1, $<a b>, 2).elems; # OUTPUT: «3␤»
  
  ```
  
  The itemizer operator will call the `.item` method on the object; it can also be called as a subroutine. Since [that is a method inherited from `Mu`](/type/Mu#method_item), objects of any class can be itemized.
  