=head1 NAME

builtins.pod - List of Perl 6 builtins

=head1 DESCRIPTION

This document is just a working document of the "known" Perl 6 built-ins.
It is not intended to be complete or authoritative -- it's just a
quick reference for those of us who want an index of the various
declarations and implementations, at least until we're able to
auto-generate such an index from the implementation code itself.

Most of the entries are extracted from readings of the various 
synopses and apocalypses documents, although some will come from
the perl6-language and perl6-compiler mailing lists and from
other email sources.

The way in which something is listed here isn't intended to constrain
implementors to a specific implementation -- it's just to indicate
how things should probably look to the perl 6 programmer.  Also, it's
entirely possible that some things are really macros (and we should
indicate such here as we discover them).

Finally, for each entry, we're only entering as much detail as we know
(or need to know) for implementation of the compiler.  

=head1 BUILT-IN OPERATORS

=head2 Numeric operators

    # addition, subtraction, multiplication, division
    multi sub *infix:<+>(Num $x, Num $y) returns Num { ... }
    multi sub *infix:<->(Num $x, Num $y) returns Num is equiv(&*infix:<+>) { ... }
    multi sub *infix:<*>(Num $x, Num $y) returns Num is tighter(&*infix:<+>) { ... }
    multi sub *infix:</>(Num $x, Num $y) returns Num is equiv(&*infix:<*>) { ... }

    # bitwise or, xor, and, shifts
    multi sub *infix:<+|>(Int $x, Int $y) returns Int is equiv(&*infix:<+>) { ... }
    multi sub *infix:<+^>(Int $x, Int $y) returns Int is equiv(&*infix:<+>) { ... }
    multi sub *infix:<+&>(Int $x, Int $y) returns Int is equiv(&*infix:<*>) { ... }
    multi sub *infix:«+<»(Int $x, Int $y) returns Int is equiv(&*infix:<*>) { ... }
    multi sub *infix:«+>»(Int $x, Int $y) returns Int is equiv(&*infix:<*>) { ... }

    # unary ops
    multi sub *prefix:<+> (Num $x) returns Num is tighter(&*infix:<*>) { ... }
    multi sub *prefix:<-> (Num $x) returns Num is equiv(&*prefix:<+>) { ... }
    multi sub *prefix:<+^>(Int $x) returns Int is equiv(&*prefix:<+>) { ... }

    # exponentiation
    multi sub *infix:<**>(Num $x, Num $y) returns Num is tighter(&*prefix:<+>) { ... }
    
=head2 String operators

    # concatenation
    multi sub *infix:<~>(Str $s1, Str $s2) returns Str is equiv(&*infix:<+>) { ... }

    # bitwise or, xor, and, shifts
    multi sub *infix:<~|>(Str $x, Str $y) returns Str is equiv(&*infix:<+>) { ... }
    multi sub *infix:<~^>(Str $x, Str $y) returns Str is equiv(&*infix:<+>) { ... }
    multi sub *infix:<~&>(Str $x, Str $y) returns Str is equiv(&*infix:<*>) { ... }
    multi sub *infix:«~<»(Str $x, Str $y) returns Str is equiv(&*infix:<*>) { ... }
    multi sub *infix:«~>»(Str $x, STr $y) returns Str is equiv(&*infix:<*>) { ... }

    # unary ops
    multi sub prefix:<~> (Str $x) returns Str is equiv(&*prefix:<+>) { ... }
    multi sub prefix:<~^>(Str $x) returns Str is equiv(&*prefix:<+>) { ... }

=head2 Boolean operators

    # boolean or, xor, and, shifts
    multi sub *infix:<?|>(Bool $x, Bool $y) returns bit is equiv(&*infix:<+>) { ... }
    multi sub *infix:<?^>(Bool $x, Bool $y) returns bit is equiv(&*infix:<+>) { ... }
    multi sub *infix:<?&>(Bool $x, Bool $y) returns bit is equiv(&*infix:<*>) { ... }

    # unary ops
    # XXX: since C<!> is equivalent to C<?^> (see S03), should it be 
    # a macro or alias of some sort?
    multi sub prefix:<?> ($x) returns bit is equiv(&*prefix:<+>) { ... }
    multi sub prefix:<?^>($x) returns bit is equiv(&*prefix:<+>) { ... }
    multi sub prefix:<!> ($x) returns bit is equiv(&*prefix:<+>) { ... }

=head2 Relational operators

    multi sub infix:<==>(Num $x, Num $y) returns bit is looser(&*infix:<..>) 
        is assoc('chain') { ... }
    multi sub infix:<!=>(Num $x, Num $y) returns bit is equiv(&*infix:<==>) { ... }
    multi sub infix:«<» (Num $x, Num $y) returns bit is equiv(&*infix:<==>) { ... }
    multi sub infix:«<=»(Num $x, Num $y) returns bit is equiv(&*infix:<==>) { ... }
    multi sub infix:«>» (Num $x, Num $y) returns bit is equiv(&*infix:<==>) { ... }
    multi sub infix:«>=»(Num $x, Num $y) returns bit is equiv(&*infix:<==>) { ... }

    multi sub infix:<eq>(Str $x, Str $y) returns bit is equiv(&*$infix:<==>) { ... }
    multi sub infix:<ne>(Str $x, Str $y) returns bit is equiv(&*$infix:<==>) { ... }
    multi sub infix:<lt>(Str $x, Str $y) returns bit is equiv(&*$infix:<==>) { ... }
    multi sub infix:<le>(Str $x, Str $y) returns bit is equiv(&*$infix:<==>) { ... }
    multi sub infix:<gt>(Str $x, Str $y) returns bit is equiv(&*$infix:<==>) { ... }
    multi sub infix:<ge>(Str $x, Str $y) returns bit is equiv(&*$infix:<==>) { ... }

    multi sub infix:<=:=>($x, $y) returns bit is equiv(&*$infix:<==>) { ... }
    
=head2 Logical operators

    multi sub infix:<&&>(Bool $x, Bool $y) returns Scalar is looser(&*infix:<==>) { ... }
    multi sub infix:<||>(Bool $x, Bool $y) returns Scalar is looser(&*infix:<&&>) { ... }
    multi sub infix:<^^>(Bool $x, Bool $y) returns Scalar is equiv(&*infix:<||>) { ... }
    multi sub infix:<//>(     $x,      $y) returns Scalar is equiv(&*infix:<||>) { ... }

    multi sub infix:<and>(Bool $x, Bool $y) returns Scalar is looser(&*infix:«==>») 
        { ... }
    multi sub infix:<or> (Bool $x, Bool $y) returns Scalar is looser(&*infix:<and>) 
        { ... }
    multi sub infix:<xor>(Bool $x, Bool $y) returns Scalar is equiv(&*infix:<or>) 
        { ... }
    multi sub infix:<err>(     $x,      $y) returns Scalar is equiv(&*infix:<or>) 
        { ... }
    multi sub infix:<not>(Bool $x)          returns bit    is tighter(&*infix:<and>)
        { ... }

=head2 Ternary operator

I'm not at all ready to tackle this one just yet.  :-)

=head2 List operators

    multi sub infix:<x> ($x, $y) returns Str  is equiv(&*infix:<*>) { ... }
    multi sub infix:<xx>(@x, $y) returns List is equiv(&*infix:<*>) { ... }

    multi sub infix:<..>  (Int $min, Int $max: Int ?$by = 1) returns List
        is tighter(&*infix:<==>) is assoc('non') { ... }
    multi sub infix:<^..> (Int $min, Int $max: Int ?$by = 1) returns List
        is equiv(&*infix:<..>) { ... }
    multi sub infix:<..^> (Int $min, Int $max: Int ?$by = 1) returns List
        is equiv(&*infix:<..>) { ... }
    multi sub infix:<^..^>(Int $min, Int $max: Int ?$by = 1) returns List
        is equiv(&*infix:<..>) { ... }
    
    multi sub postfix:<...>(Int $min: Int ?$by = 1) return List 
        is equiv(&*infix:<..>) { ... }

=head1 BUILT-IN FUNCTIONS

XXX: Is there a criterion that we use to choose between defining 
something as a multi sub versus a class/object method?

=head2 Misc functions

    multi sub *perl($x)     returns Str { ... }
    multi sub *eval(Str $x) returns Any { ... }

=head2 List functions

    # not sure about the placement of the colon in the following functions
    multi sub *map(&code: *@list) returns List { ... }
    multi sub *map(@list: *&code) returns List { ... }

    multi sub *grep(&code: *@list) returns List { ... }
    multi sub *grep(@list: *&code) returns List { ... }

    multi sub *zip(*@args) returns List { ... }

    multi sub *join(Str $by, *@list) returns Str { ... }

=head2 Array functions

    multi sub *keys(@array) returns List { ... }
    multi sub *kv  (@array) returns List { ... }

    multi sub *push(@array is rw: *@list)    returns Int { ... }
    multi sub *unshift(@array is rw: *@list) returns Int { ... }
    multi sub *pop(@array is rw)             returns Scalar { ... }
    multi sub *shift(@array is rw)           returns Scalar { ... }
    
    multi sub *join(@array: Str $by) returns Str { ... }

=head2 Hash functions

    multi sub *keys  (%x) returns List { ... }
    multi sub *values(%x) returns List { ... }
    multi sub *kv    (%x) returns List { ... }

=head2 Junction functions

    # XXX: should these be Disjunction, Conjunction, etc...?
    multi sub *any (*@elem) returns Junction { ... }
    multi sub *all (*@elem) returns Junction { ... }
    multi sub *one (*@elem) returns Junction { ... }
    multi sub *none(*@elem) returns Junction { ... }

=head1 BUILT-IN CLASSES (and methods as appropriate)

XXX: Should we go ahead and define these here...?

=head1 BUILT-IN ENUMS

    our bit enum *bool <false true>;
    our bit enum *taint <untainted tainted>;

