I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Exponentiation with infix operators in (or operating on) the base

Exponentiation with infix operators in (or operating on) the base is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

(Many programming languages,   especially those with extended─precision integer arithmetic,   usually support one of `**`, `^`, `↑` or some such for exponentiation.)

Some languages treat/honor infix operators when performing exponentiation   (raising numbers to some power by the language's exponentiation operator,   if the computer programming language has one).

Other programming languages may make use of the   POW   or some other BIF   (Built─In Ffunction),   or some other library service.

If your language's exponentiation operator is not one of the usual ones, please comment on how to recognize it.

This task will deal with the case where there is some form of an   infix operator   operating in   (or operating on)   the base.

Example

A negative five raised to the 3rd power could be specified as:

```   -5  ** 3          or as
-(5) ** 3          or as
(-5) ** 3          or as something else
```

(Not all computer programming languages have an exponential operator and/or support these syntax expression(s).

•   compute and display exponentiation with a possible infix operator, whether specified and/or implied/inferred.
•   Raise the following numbers   (integer or real):
•   -5     and
•   +5
•   to the following powers:
•   2nd     and
•   3rd
•   using the following expressions   (if applicable in your language):
•   -x**p
•   -(x)**p
•   (-x)**p
•   -(x**p)
•   Show here (on this page) the four (or more) types of symbolic expressions for each number and power.

Try to present the results in the same format/manner as the other programming entries to make any differences apparent.

The variables may be of any type(s) that is/are applicable in your language.

References

## ALGOL 68

In Algol 68, all unary operators have a higher precedence than any binary operator.
Algol 68 also allows UP and ^ for the exponentiation operator.

`BEGIN    # show the results of exponentiation and unary minus in various combinations #    FOR x FROM -5 BY 10 TO 5 DO        FOR p FROM 2 TO 3 DO            print( ( "x = ", whole( x, -2 ), " p = ", whole( p, 0 ) ) );            print( ( "     -x**p  ", whole(   -x**p,  -4 ) ) );            print( ( "   -(x)**p  ", whole( -(x)**p,  -4 ) ) );            print( ( "   (-x)**p  ", whole( (-x)**p,  -4 ) ) );            print( ( "    -(x**p) ", whole(  -(x**p), -4 ) ) );            print( ( newline ) );        OD    ODEND`
Output:
```x = -5 p = 2     -x**p    25   -(x)**p    25   (-x)**p    25    -(x**p)  -25
x = -5 p = 3     -x**p   125   -(x)**p   125   (-x)**p   125    -(x**p)  125
x =  5 p = 2     -x**p    25   -(x)**p    25   (-x)**p    25    -(x**p)  -25
x =  5 p = 3     -x**p  -125   -(x)**p  -125   (-x)**p  -125    -(x**p) -125
```

## F#

F# does not support the ** operator for integers but for floats:

` printfn "-5.0**2.0=%f; -(5.0**2.0)=%f" (-5.0**2.0) (-(5.0**2.0)) `
Output:
```-5.0**2.0=25.000000; -(5.0**2.0)=-25.000000
```

## Factor

`USING: infix locals prettyprint sequencessequences.generalizations sequences.repeating ; :: row ( x p -- seq )    x p "-x**p" [infix -x**p infix]    "-(x)**p" [infix -(x)**p infix]    "(-x)**p" [infix (-x)**p infix]    "-(x**p)" [infix -(x**p) infix] 10 narray ; { "x value" "p value" } { "expression" "result" } 8 cycle append-5 2 row-5 3 row5 2 row5 3 row5 narray simple-table.`
Output:
```x value p value expression result expression result expression result expression result
-5      2       -x**p      25     -(x)**p    25     (-x)**p    25     -(x**p)    -25
-5      3       -x**p      125    -(x)**p    125    (-x)**p    125    -(x**p)    125
5       2       -x**p      25     -(x)**p    25     (-x)**p    25     -(x**p)    -25
5       3       -x**p      -125   -(x)**p    -125   (-x)**p    -125   -(x**p)    -125
```

## Go

Go uses the math.Pow function for exponentiation and doesn't support operator overloading at all. Consequently, it is not possible to conjure up an infix operator to do the same job.

Perhaps the closest we can get is to define a derived type (float say) based on float64 and then give it a method with a short name (p say) to provide exponentiation.

This looks odd but is perfectly workable as the following example shows. However, as a method call, x.p is always going to take precedence over the unary minus operator and will always require the exponent to be enclosed in parentheses.

Note that we can't call the method (or similar) because identifiers in Go must begin with a Unicode letter and using a non-ASCII symbol would be awkward to type on some keyboards in any case.

`package main import (    "fmt"    "math") type float float64 func (f float) p(e float) float { return float(math.Pow(float64(f), float64(e))) } func main() {    ops := []string{"-x.p(e)", "-(x).p(e)", "(-x).p(e)", "-(x.p(e))"}    for _, x := range []float{float(-5), float(5)} {        for _, e := range []float{float(2), float(3)} {            fmt.Printf("x = %2.0f e = %0.0f | ", x, e)            fmt.Printf("%s = %4.0f | ", ops, -x.p(e))            fmt.Printf("%s = %4.0f | ", ops, -(x).p(e))            fmt.Printf("%s = %4.0f | ", ops, (-x).p(e))            fmt.Printf("%s = %4.0f\n", ops, -(x.p(e)))        }    }}`
Output:
```x = -5 e = 2 | -x.p(e) =  -25 | -(x).p(e) =  -25 | (-x).p(e) =   25 | -(x.p(e)) =  -25
x = -5 e = 3 | -x.p(e) =  125 | -(x).p(e) =  125 | (-x).p(e) =  125 | -(x.p(e)) =  125
x =  5 e = 2 | -x.p(e) =  -25 | -(x).p(e) =  -25 | (-x).p(e) =   25 | -(x.p(e)) =  -25
x =  5 e = 3 | -x.p(e) = -125 | -(x).p(e) = -125 | (-x).p(e) = -125 | -(x.p(e)) = -125
```

## Julia

In Julia, the ^ symbol is the power infix operator. The ^ operator has a higher precedence than the - operator, so -5^2 is -25 and (-5)^2 is 25.

` for x in [-5, 5], p in [2, 3]    println("x is", lpad(x, 3), ", p is \$p, -x^p is", lpad(-x^p, 4), ", -(x)^p is",        lpad(-(x)^p, 5), ", (-x)^p is", lpad((-x)^p, 5), ", -(x^p) is", lpad(-(x^p), 5))end `
Output:
```x is -5, p is 2, -x^p is -25, -(x)^p is  -25, (-x)^p is   25, -(x^p) is  -25
x is -5, p is 3, -x^p is 125, -(x)^p is  125, (-x)^p is  125, -(x^p) is  125
x is  5, p is 2, -x^p is -25, -(x)^p is  -25, (-x)^p is   25, -(x^p) is  -25
x is  5, p is 3, -x^p is-125, -(x)^p is -125, (-x)^p is -125, -(x^p) is -125
```

## Phix

Phix has a power() function instead of an infix operator, hence there are only two possible syntaxes, with the obvious outcomes.
(Like Go, Phix does not support operator overloading or definition at all.)

`for x=-5 to 5 by 10 do    for p=2 to 3 do        printf(1,"x = %2d, p = %d, power(-x,p) = %4d, -power(x,p) = %4d\n",{x,p,power(-x,p),-power(x,p)})    end forend for`
Output:
```x = -5, p = 2, power(-x,p) =   25, -power(x,p) =  -25
x = -5, p = 3, power(-x,p) =  125, -power(x,p) =  125
x =  5, p = 2, power(-x,p) =   25, -power(x,p) =  -25
x =  5, p = 3, power(-x,p) = -125, -power(x,p) = -125
```

## Raku

In Raku by default, infix exponentiation binds tighter than unary negation. It is trivial however to define your own infix operators with whatever precedence level meets the needs of your program.

A slight departure from the task specs. Use `1 + {expression}` rather than just `{expression}` to better demonstrate the relative precedence levels. Where `{expression}` is one of:

• `-x{exponential operator}p`
• `-(x){exponential operator}p`
• `((-x){exponential operator}p)`
• `-(x{exponential operator}p)`

Also add a different grouping: `(1 + -x){exponential operator}p`

`sub infix:<↑> is looser(&prefix:<->) { \$^a ** \$^b }sub infix:<^> is looser(&infix:<->)  { \$^a ** \$^b } use MONKEY; for 'Default precedence: infix exponentiation is tighter (higher) precedence than unary negation.',    ('1 + -\$x**\$p', '1 + (-\$x)**\$p', '1 + (-(\$x)**\$p)', '(1 + -\$x)**\$p', '1 + -(\$x**\$p)'),     "\nEasily modified: custom loose infix exponentiation is looser (lower) precedence than unary negation.",    ('1 + -\$x↑\$p ', '1 + (-\$x)↑\$p ', '1 + (-(\$x)↑\$p) ', '(1 + -\$x)↑\$p ', '1 + -(\$x↑\$p) '),     "\nEven moreso: custom looser infix exponentiation is looser (lower) precedence than infix subtraction.",    ('1 + -\$x^\$p ', '1 + (-\$x)^\$p ', '1 + (-(\$x)^\$p) ', '(1 + -\$x)^\$p ', '1 + -(\$x^\$p) ')    -> \$message, \$ops {    say \$message;    for -5, 5 X 2, 3 -> (\$x, \$p) {        printf "x = %2d  p = %d", \$x, \$p;        -> \$op { printf " │ %s = %4d", \$op, EVAL \$op } for |\$ops;        print "\n";    }}`
Output:
```Default precedence: infix exponentiation is tighter (higher) precedence than unary negation.
x = -5  p = 2 │ 1 + -\$x**\$p =  -24 │ 1 + (-\$x)**\$p =   26 │ 1 + (-(\$x)**\$p) =  -24 │ (1 + -\$x)**\$p =   36 │ 1 + -(\$x**\$p) =  -24
x = -5  p = 3 │ 1 + -\$x**\$p =  126 │ 1 + (-\$x)**\$p =  126 │ 1 + (-(\$x)**\$p) =  126 │ (1 + -\$x)**\$p =  216 │ 1 + -(\$x**\$p) =  126
x =  5  p = 2 │ 1 + -\$x**\$p =  -24 │ 1 + (-\$x)**\$p =   26 │ 1 + (-(\$x)**\$p) =  -24 │ (1 + -\$x)**\$p =   16 │ 1 + -(\$x**\$p) =  -24
x =  5  p = 3 │ 1 + -\$x**\$p = -124 │ 1 + (-\$x)**\$p = -124 │ 1 + (-(\$x)**\$p) = -124 │ (1 + -\$x)**\$p =  -64 │ 1 + -(\$x**\$p) = -124

Easily modified: custom loose infix exponentiation is looser (lower) precedence than unary negation.
x = -5  p = 2 │ 1 + -\$x↑\$p  =   26 │ 1 + (-\$x)↑\$p  =   26 │ 1 + (-(\$x)↑\$p)  =   26 │ (1 + -\$x)↑\$p  =   36 │ 1 + -(\$x↑\$p)  =  -24
x = -5  p = 3 │ 1 + -\$x↑\$p  =  126 │ 1 + (-\$x)↑\$p  =  126 │ 1 + (-(\$x)↑\$p)  =  126 │ (1 + -\$x)↑\$p  =  216 │ 1 + -(\$x↑\$p)  =  126
x =  5  p = 2 │ 1 + -\$x↑\$p  =   26 │ 1 + (-\$x)↑\$p  =   26 │ 1 + (-(\$x)↑\$p)  =   26 │ (1 + -\$x)↑\$p  =   16 │ 1 + -(\$x↑\$p)  =  -24
x =  5  p = 3 │ 1 + -\$x↑\$p  = -124 │ 1 + (-\$x)↑\$p  = -124 │ 1 + (-(\$x)↑\$p)  = -124 │ (1 + -\$x)↑\$p  =  -64 │ 1 + -(\$x↑\$p)  = -124

Even moreso: custom looser infix exponentiation is looser (lower) precedence than infix subtraction.
x = -5  p = 2 │ 1 + -\$x^\$p  =   36 │ 1 + (-\$x)^\$p  =   36 │ 1 + (-(\$x)^\$p)  =   26 │ (1 + -\$x)^\$p  =   36 │ 1 + -(\$x^\$p)  =  -24
x = -5  p = 3 │ 1 + -\$x^\$p  =  216 │ 1 + (-\$x)^\$p  =  216 │ 1 + (-(\$x)^\$p)  =  126 │ (1 + -\$x)^\$p  =  216 │ 1 + -(\$x^\$p)  =  126
x =  5  p = 2 │ 1 + -\$x^\$p  =   16 │ 1 + (-\$x)^\$p  =   16 │ 1 + (-(\$x)^\$p)  =   26 │ (1 + -\$x)^\$p  =   16 │ 1 + -(\$x^\$p)  =  -24
x =  5  p = 3 │ 1 + -\$x^\$p  =  -64 │ 1 + (-\$x)^\$p  =  -64 │ 1 + (-(\$x)^\$p)  = -124 │ (1 + -\$x)^\$p  =  -64 │ 1 + -(\$x^\$p)  = -124```

## REXX

`/*REXX program shows exponentition with an  infix operator  (implied and/or specified).*/_= '─';   ! = '║';   mJunct= '─╫─';   bJunct= '─╨─'       /*define some special glyphs. */ say @('  x  ', 5)  @("  p  ", 5)        !say @('value', 5)  @("value", 5) copies(!        @('expression',10)  @("result",6)" ",  4)say @(''  , 5, _)  @("",   5, _)copies(mJunct || @('',       10, _)  @("",   6, _)   ,  4)    do    x=-5  to 5  by 10                       /*assign   -5    and    5    to    X.  */      do p= 2  to 3                              /*assign    2    and    3    to    P.  */                            a =  -x**p ;   b =  -(x)**p ;   c =  (-x)**p ;   d =  -(x**p)                           ae= '-x**p';   be= "-(x)**p";   ce= '(-x)**p';   de= "-(x**p)"      say @(x,5)  @(p,5) ! @(ae, 10)    right(a, 5)" " ,                         ! @(be, 10)    right(b, 5)" " ,                         ! @(ce, 10)    right(c, 5)" " ,                         ! @(de, 10)    right(d, 5)      end   /*p*/   end      /*x*/ say @(''  , 5, _)  @('',   5, _)copies(bJunct || @('',       10, _)  @('',   6, _)   ,  4)exit 0                                           /*stick a fork in it,  we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/@:    parse arg txt, w, fill;  if fill==''  then fill= ' ';   return center( txt, w, fill) `
output   when using the internal default input:
```  x     p   ║
value value ║ expression result ║ expression result ║ expression result ║ expression result
───── ──────╫─────────── ───────╫─────────── ───────╫─────────── ───────╫─────────── ──────
-5     2   ║   -x**p       25  ║  -(x)**p      25  ║  (-x)**p      25  ║  -(x**p)     -25
-5     3   ║   -x**p      125  ║  -(x)**p     125  ║  (-x)**p     125  ║  -(x**p)     125
5     2   ║   -x**p       25  ║  -(x)**p      25  ║  (-x)**p      25  ║  -(x**p)     -25
5     3   ║   -x**p     -125  ║  -(x)**p    -125  ║  (-x)**p    -125  ║  -(x**p)    -125
───── ──────╨─────────── ───────╨─────────── ───────╨─────────── ───────╨─────────── ──────
```

## Python

`from itertools import product xx = '-5 +5'.split()pp = '2 3'.split()texts = '-x**p -(x)**p (-x)**p -(x**p)'.split() print('Integer variable exponentiation')for x, p in product(xx, pp):    print(f'  x,p = {x:2},{p}; ', end=' ')    x, p = int(x), int(p)    print('; '.join(f"{t} =={eval(t):4}" for t in texts)) print('\nBonus integer literal exponentiation')X, P = 'xp'xx.insert(0, ' 5')texts.insert(0, 'x**p')for x, p in product(xx, pp):    texts2 = [t.replace(X, x).replace(P, p) for t in texts]    print(' ', '; '.join(f"{t2} =={eval(t2):4}" for t2 in texts2))`
Output:
```Integer variable exponentiation
x,p = -5,2;  -x**p == -25; -(x)**p == -25; (-x)**p ==  25; -(x**p) == -25
x,p = -5,3;  -x**p == 125; -(x)**p == 125; (-x)**p == 125; -(x**p) == 125
x,p = +5,2;  -x**p == -25; -(x)**p == -25; (-x)**p ==  25; -(x**p) == -25
x,p = +5,3;  -x**p ==-125; -(x)**p ==-125; (-x)**p ==-125; -(x**p) ==-125

Bonus integer literal exponentiation
5**2 ==  25; - 5**2 == -25; -( 5)**2 == -25; (- 5)**2 ==  25; -( 5**2) == -25
5**3 == 125; - 5**3 ==-125; -( 5)**3 ==-125; (- 5)**3 ==-125; -( 5**3) ==-125
-5**2 == -25; --5**2 ==  25; -(-5)**2 == -25; (--5)**2 ==  25; -(-5**2) ==  25
-5**3 ==-125; --5**3 == 125; -(-5)**3 == 125; (--5)**3 == 125; -(-5**3) == 125
+5**2 ==  25; -+5**2 == -25; -(+5)**2 == -25; (-+5)**2 ==  25; -(+5**2) == -25
+5**3 == 125; -+5**3 ==-125; -(+5)**3 ==-125; (-+5)**3 ==-125; -(+5**3) ==-125```

## Wren

Library: Wren-fmt

Wren uses the pow() method for exponentiation of numbers and, whilst it supports operator overloading, there is no way of adding a suitable infix operator to the existing Num class.

Also inheriting from the Num class is not recommended and will probably be banned altogether from the next version.

However, what we can do is to wrap Num objects in a new Num2 class and then add exponentiation and unary minus operators to that.

Ideally what we'd like to do is to use a new operator such as '**' for exponentiation (because '^' is the bitwise exclusive or operator) but we can only overload existing operators with their existing precedence and so, for the purposes of this task, '^' is the only realistic choice.

`import "/fmt" for Fmt class Num2 {    construct new(n) { _n = n }     n { _n}     ^(exp) {        if (exp is Num2) exp = exp.n        return Num2.new(_n.pow(exp))    }     - { Num2.new(-_n) }     toString { _n.toString }} var ops = ["-x^p", "-(x)^p", "(-x)^p", "-(x^p)"]  for (x in [Num2.new(-5), Num2.new(5)]) {    for (p in [Num2.new(2), Num2.new(3)]) {        Fmt.write("x = \$2s p = \$s | ", x, p)        Fmt.write("\$s = \$4s | ", ops, -x^p)        Fmt.write("\$s = \$4s | ", ops, -(x)^p)        Fmt.write("\$s = \$4s | ", ops, (-x)^p)        Fmt.print("\$s = \$4s",    ops, -(x^p))    }}`
Output:
```x = -5 p = 2 | -x^p =   25 | -(x)^p =   25 | (-x)^p =   25 | -(x^p) =  -25
x = -5 p = 3 | -x^p =  125 | -(x)^p =  125 | (-x)^p =  125 | -(x^p) =  125
x =  5 p = 2 | -x^p =   25 | -(x)^p =   25 | (-x)^p =   25 | -(x^p) =  -25
x =  5 p = 3 | -x^p = -125 | -(x)^p = -125 | (-x)^p = -125 | -(x^p) = -125
```