/*
The following code produces this output:

5! = 120
5^3 = 125
sqrt(2) = 1.4142135614529252
d(4) = 1+2+3+4 = 10
4! = 24
e^2 = 7.389120665712596

If you have an HP-calculator you might understand this. Otherwise I recommend the documentation for pagkalos found at http://sourceforge.net/projects/pagkalos/.
*/

fac :
    if dup 0 = ;
        0 drop
        1 return
    fi
    dup 1 -
    fac * ;

// Calculate a ^ b. b must be an integer
power :
    1 pick
    loop
        1 pick 1 -
        2 swap
        1 = leaveif
        2 pick *
    end
    1 drop
    1 drop ;

// Calculate square roots using Divide & Conquer
sqrt :
    dup
    0.0 1 swap
    loop
        // Calculate the middle of the current intervall
        1 pick 1 pick + 2 /
        // Decide for the upper or lower intervall
        if dup dup * 4 pick > ; 1 else 2 fi swap
        0 drop
            dup dup *
            3 pick - 0.0000000001 < leaveif
    end
    + 2 / 1 drop ;

// Apply a function to an array arr:
//  a(0) := arr[0] arr[1] f
//  a(n) := a(n-1) arr[n] f
// Result := a(arr.length)
apply :
    f pvar
    0 i pvar dup 0 get
    loop
        1 swap dup size ++i = leaveif
        dup i get 2 pick f run
        2 swap 0 drop 1 swap
    end
    0 drop ;

// Power series
// Usage: a(n) x pr
// Example: a(n) for e^x: ': 1.0 1 swap fac / ;
//                            <=> 1 / x!
powerseries :
    eq pvar
    0 i pvar
    0.0 // Initial value
    loop // Add up the first 15 emelments of the series
        i eq run // Genereate a(n)
        2 pick i pow // z to the power of n
        * +
        i++ 15 > leaveif
    end
    1 drop ;

// Shortcut for the exponetial function
e^ : ': 1.0 1 swap fac / ; powerseries ;
    

"5! = " 5 fac + .
"5^3 = " 5 3 power + .
"sqrt(2) = " 2 sqrt + .
"d(4) = 1+2+3+4 = " [1, 2, 3, 4] '+ apply + .
"4! = " [1, 2, 3, 4] '* apply + .
"e^2 = " 2 e^ + .