txt: ## set.md
  class Set
  
  Immutable collection of distinct objects
  
  ```raku
  class Set does Setty { }
  ```
  
  A `Set` is an immutable set, meaning a collection of distinct elements in no particular order. (For *mutable* sets, see [`SetHash`](/type/SetHash) instead.)
  
  Objects/values of any type are allowed as set elements. Within a `Set`, every element is guaranteed to be unique (in the sense that no two elements would compare positively with the [===](/routine/===) operator):
  
  ```raku
  my $fruits = set <peach apple orange apple apple>;
  
  say $fruits.elems;      # OUTPUT: «3␤»
  say $fruits.keys.sort;  # OUTPUT: «apple orange peach␤»
  
  ```
  
  `Set`s can be treated as object hashes using the `{ }` postcircumfix operator, which returns the value `True` for keys that are elements of the set, and `False` for keys that aren't:
  
  ```raku
  my $fruits = set <peach apple orange apple apple>;
  say $fruits<apple>;  # OUTPUT: «True␤»
  say $fruits<kiwi>;   # OUTPUT: «False␤»
  ```
  
  # [Creating `Set` objects](#class_Set "go to top of document")[§](#Creating_Set_objects "direct link")
  
  `Set`s can be composed using the [set](#sub_set) subroutine (or `Set.new`, for which it is a shorthand). Any positional parameters, regardless of their type, become elements of the set:
  
  ```raku
  my $n = set "zero" => 0, "one" => 1, "two" => 2;
  say $n.keys.raku;        # OUTPUT: «(:two(2), :zero(0), :one(1)).Seq␤»
  say $n.keys.map(&WHAT);  # OUTPUT: «((Pair) (Pair) (Pair))␤»
  ```
  
  Alternatively, the `.Set` coercer (or its functional form, `Set()`) can be called on an existing object to coerce it to a `Set`. Its semantics depend on the type and contents of the object. In general it evaluates the object in list context and creates a set with the resulting items as elements, although for Hash-like objects or Pair items, only the keys become elements of the set - and keys mapped to values which boolify to `False` are skipped:
  
  ```raku
  my $n = ("zero" => 0, "one" => 1, "two" => 2).Set;
  say $n.keys.raku;        # OUTPUT: «("one", "two").Seq␤»
  say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤»
  ```
  
  Furthermore, you can get a `Set` by using set operators (see next section) on objects of other types such as [`List`](/type/List), which will act like they internally call `.Set` on them before performing the operation. Be aware of the tight precedence of those operators though, which may require you to use parentheses around arguments:
  
  ```raku
  say (1..5) (^) 4;  # OUTPUT: «Set(1 2 3 5)␤»
  ```
  
  You can also create a `Set` with the `.new` method.
  
  ```raku
  my $fruits = Set.new( <peach apple orange apple apple> );
  ```
  
  Since 6.d (2019.03 and later) you can also use this syntax for parameterization of the `Set`, to specify which type of values are acceptable:
  
  ```raku
  # only allow strings (Str) in the Set
  my $fruits = Set[Str].new( <peach apple orange apple apple> );
  
  # only allow whole numbers (Int) in the Set
  my $fruits = Set[Int].new( <peach apple orange apple apple> );
  # Type check failed in binding; expected Int but got Str ("peach")
  ```
  
  Finally, you can create `Set` masquerading as a hash (actually, declare a variable [`Associative`](/type/Associative) by using the corresponding sigil) by using the `is` trait:
  
  ```raku
  my %s is Set = <a b c>;
  say %s<a>;  # OUTPUT: «True␤»
  say %s<d>;  # OUTPUT: «False␤»
  ```
  
  Since 6.d (2019.03 and later), this syntax also allows you to specify the type of values you would like to allow:
  
  ```raku
  # limit to strings
  my %s is Set[Str] = <a b c>;
  say %s<a>;  # OUTPUT: «True␤»
  say %s<d>;  # OUTPUT: «False␤»
  
  # limit to whole numbers
  my %s is Set[Int] = <a b c>;
  # Type check failed in binding; expected Int but got Str ("a")
  ```
  
  # [Operators](#class_Set "go to top of document")[§](#Operators "direct link")
  
  See [Operators with set semantics](/language/setbagmix#Operators_with_set_semantics) for a complete list of "set operators" applicable to, among other types, `Set`.
  
  Examples:
  
  ```raku
  my ($a, $b) = set(1, 2, 3), set(2, 4);
  
  say $a (<) $b;  # OUTPUT: «False␤»
  say $a (&) $b;  # OUTPUT: «Set(2)␤»
  say $a (^) $b;  # OUTPUT: «Set(1 3 4)␤»
  
  # Unicode versions:
  say $a ⊂ $b;  # OUTPUT: «False␤»
  say $a ∩ $b;  # OUTPUT: «Set(2)␤»
  say $a ⊖ $b;  # OUTPUT: «Set(1 3 4)␤»
  
  ```
  
  # [Subroutines](#class_Set "go to top of document")[§](#Subroutines "direct link")
  
  ## [sub set](#class_Set "go to top of document")[§](#sub_set "direct link")
  
  ```raku
  sub set(*@args --> Set)
  ```
  
  Creates a `Set` from the given `@args`
  
  # [See Also](#class_Set "go to top of document")[§](#See_Also "direct link")
  
  [Sets, Bags, and Mixes](/language/setbagmix)
  
  # [Typegraph](# "go to top of document")[§](#typegraphrelations "direct link")
  
  Type relations for `Set`
  
  
  
  raku-type-graph
  
  
  
  Set
  Set
  
  
  Any
  Any
  
  
  Set->Any
  
  
  
  Setty
  Setty
  
  
  Set->Setty
  
  
  
  Mu
  Mu
  
  
  Any->Mu
  
  
  
  Associative
  Associative
  
  
  QuantHash
  QuantHash
  
  
  QuantHash->Associative
  
  
  
  Setty->QuantHash
  
  [Expand chart above](/assets/typegraphs/Set.svg)
  