=begin pod :kind("Language") :subkind("Language") :category("fundamental")

=TITLE Sets, bags, and mixes

=SUBTITLE Unordered collections of unique and weighted objects in Raku

=head1 Introduction

The six collection classes are L<Set|/type/Set>, L<SetHash|/type/SetHash>,
L<Bag|/type/Bag>, L<BagHash|/type/BagHash>, L<Mix|/type/Mix> and
L<MixHash|/type/MixHash>.   They all share similar semantics.

In a nutshell, these classes hold, in general, unordered collections of
objects, much like an L<object hash|/type/Hash#index-entry-object_hash>.
The L<QuantHash|/type/QuantHash> role is the role that is implemented by all
of these classes: therefore they are also referenced as C<QuantHash>es.

C<Set> and C<SetHash> also implement the L<Setty|/type/Setty> role,
C<Bag> and C<BagHash> implement the L<Baggy|/type/Baggy> role, C<Mix> and
C<MixHash> implement the L<Mixy|/type/Mixy> role (which itself implements
the C<Baggy> role).

Sets only consider if objects in the collection are present or not, bags can
hold several objects of the same kind, and mixes also allow fractional (and
negative) weights. The regular versions are immutable, the I<-Hash> versions
are mutable.

Let's elaborate on that. If you want to collect objects in a container but
you do not care about the order of these objects, Raku provides these
I<unordered> collection types.  Being unordered, these containers can be more
efficient than L<Lists|/type/List> or L<Arrays|/type/Array> for looking up
elements or dealing with repeated items.

On the other hand, if you want to get the contained objects (elements)
B<without duplicates> and you only care I<whether> an element is in the
collection or not, you can use a L<Set|/type/Set> or L<SetHash|/type/SetHash>.

If you want to get rid of duplicates but still preserve order, take a look
at the L<unique|/routine/unique> routine for L<List|/type/List>.

=begin comment
=defn  Set or SetHash
Collection of distinct objects
=end comment

If you want to keep track of the B<number of times each object appeared>,
you can use a L<Bag|/type/Bag> or L<BagHash|/type/BagHash>. In these
C<Baggy> containers each element has a weight (an unsigned integer)
indicating the number of times the same object has been included in the
collection.

The types L<Mix|/type/Mix> and L<MixHash|/type/MixHash> are similar
to L<Bag|/type/Bag> and L<BagHash|/type/BagHash>, but they also
allow B<fractional and negative weights>.

L<Set|/type/Set>, L<Bag|/type/Bag>, and L<Mix|/type/Mix> are I<immutable> types.
Use the mutable variants L<SetHash|/type/SetHash>, L<BagHash|/type/BagHash>,
and L<MixHash|/type/MixHash> if you want to add or remove elements after the
container has been constructed.

For one thing, as far as they are concerned, identical objects refer to the
same element – where identity is determined using the L<WHICH|/routine/WHICH>
method (i.e. the same way that the L<===|/routine/===> operator checks identity). For value
types like C<Str>, this means having the same value; for reference types
like C<Array>, it means referring to the same object instance.

Secondly, they provide a Hash-like interface where the actual elements of
the collection (which can be objects of any type) are the 'keys', and the
associated weights are the 'values':

=table
                      value of $a{$b} if $b       value of $a{$b} if $b
    type of $a        is an element               is not an element
    -------------     ----------------------      ---------------------
    Set / SetHash     True                        False
    Bag / BagHash     a positive integer          0
    Mix / MixHash     a non-zero real number      0

=head1 Operators with set semantics

There are several infix operators devoted to performing common operations
using C<QuantHash> semantics.  Since that is a mouthful, these operators
are usually referred to as "set operators".

This does B<not> mean that the parameters of these operators must always be
C<Set>, or even a more generic C<QuantHash>.  It just means that the logic
that is applied to the operators is the logic of
L<Set Theory|https://en.wikipedia.org/wiki/Set_theory>.

These infixes can be written using the Unicode character that represents the
function (like C<∈> or C<∪>), or with an equivalent ASCII version (like
C<(elem)> or C<(|)>).

So explicitly using C<Set> (or C<Bag> or C<Mix>) objects with these infixes is
unnecessary.  All set operators work with all possible arguments, including
(since 6.d) those that are not explicitly set-like.  If necessary, a coercion
will take place internally: but in many cases that is not actually needed.

However, if a C<Bag> or C<Mix> is one of the parameters to these set operators,
then the semantics will be upgraded to that type (where C<Mix> supersedes
C<Bag> if both types happen to be used).

=head2 Set operators that return C<Bool>

=head3 infix (elem), infix ∈

Returns C<True> if C<$a> is an B<element> of C<$b>, else C<False>.
L<More information|/language/operators#infix_(elem),_infix_∈>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Element_(mathematics)#Notation_and_terminology>.

=head3 infix ∉

Returns C<True> if C<$a> is B<not> an element of C<$b>, else C<False>.
L<More information|/language/operators#infix_∉>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Element_(mathematics)#Notation_and_terminology>.

=head3 infix (cont), infix ∋

Returns C<True> if C<$a> B<contains> C<$b> as an element, else C<False>.
L<More information|/language/operators#infix_(cont),_infix_∋>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Element_(mathematics)#Notation_and_terminology>.

=head3 infix ∌

Returns C<True> if C<$a> does B<not> contain C<$b>, else C<False>.
L<More information|/language/operators#infix_∌>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Element_(mathematics)#Notation_and_terminology>.

=head3 infix (<=), infix ⊆

Returns C<True> if C<$a> is a B<subset> or is equal to C<$b>, else C<False>.
L<More information|/language/operators#infix_(<=),_infix_⊆>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Subset#Definitions>.

=head3 infix ⊈

Returns C<True> if C<$a> is B<not> a B<subset> nor equal to C<$b>, else C<False>.
L<More information|/language/operators#infix_⊈>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Subset#Definitions>.

=head3 infix (<), infix ⊂

Returns C<True> if C<$a> is a B<strict subset> of C<$b>, else C<False>.
L<More information|/language/operators#infix_(<),_infix_⊂>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Subset#Definitions>.

=head3 infix ⊄

Returns C<True> if C<$a> is B<not> a B<strict subset> of C<$b>, else C<False>.
L<More information|/language/operators#infix_⊄>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Subset#Definitions>.

=head3 infix (>=), infix ⊇

Returns C<True> if C<$a> is a B<superset> of or equal to C<$b>, else C<False>.
L«More information|/language/operators#infix_(>=),_infix_⊇»,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Subset#Definitions>.

=head3 infix ⊉

Returns C<True> if C<$a> is B<not> a B<superset> nor equal to C<$b>, else C<False>.
L<More information|/language/operators#infix_⊉>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Subset#Definitions>.

=head3 infix (>), infix ⊃

Returns C<True> if C<$a> is a B<strict superset> of C<$b>, else C<False>.
L«More information|/language/operators#infix_(>),_infix_⊃»,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Subset#Definitions>.

=head3 infix ⊅

Returns C<True> if C<$a> is B<not> a B<strict superset> of C<$b>, else C<False>.
L<More information|/language/operators#infix_⊅>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Subset#Definitions>.

=head3 infix (==), infix ≡

Returns C<True> if C<$a> and C<$b> are B<identical>, else C<False>.
L<More information|/language/operators#infix_≡>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Equality_(mathematics)#Equality_in_set_theory>.

=head3 infix ≢

Returns C<True> if C<$a> and C<$b> are B<not identical>, else C<False>.
L<More information|/language/operators#infix_≢>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Equality_(mathematics)#Equality_in_set_theory>.

=head2 Set operators that return a C<QuantHash>

=head3 infix (|), infix ∪

Returns the B<union> of all its arguments.
L<More information|/language/operators#infix_(|),_infix_∪>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Union_(set_theory)>.

=head3 infix (&), infix ∩

Returns the B<intersection> of all of its arguments.
L<More information|/language/operators#infix_(&),_infix_∩>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Intersection_(set_theory)>.

=head3 infix (-), infix ∖

Returns the B<set difference> of all its arguments.
L<More information|/language/operators#infix_(-),_infix_∖>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement>.

=head3 infix (^), infix ⊖

Returns the B<symmetric set difference> of all its arguments.
L<More information|/language/operators#infix_(^),_infix_⊖>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Symmetric_difference>.

=head2 Set operators that return a C<Baggy>

=head3 infix (.), infix ⊍

Returns the Baggy B<multiplication> of its arguments.
L<More information|/language/operators#infix_(.),_infix_⊍>.

=head3 infix (+), infix ⊎

Returns the Baggy B<addition> of its arguments.
L<More information|/language/operators#infix_(+),_infix_⊎>.

=head2 Terms related to set operators

=head3 term ∅

The empty set.  L<More information|/language/terms#term_∅>,
L<Wikipedia definition|https://en.wikipedia.org/wiki/Empty_set>.

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
