' --- Recursion and Higher-Order Functions in jdBasic ---
CLS
' ===============================================
' A recursive function calls itself to solve a problem.
' ===============================================
PRINT "--- Recursion Demo: Factorial ---"

FUNC FACTORIAL(N)
    ' The base case is essential to stop the recursion.
    IF N <= 1 THEN RETURN 1

    ' The recursive step: call itself with a smaller problem.
    RETURN N * FACTORIAL(N - 1)
ENDFUNC

PRINT "Factorial of 6 is:"; FACTORIAL(6)
PRINT ""

PRINT "--- Higher-Order Function Demo: MAP ---"
' =========================================================
' A higher-order function takes another function as an argument.
' =========================================================

' A simple function we can pass to AMAP.
FUNC SQUARE_IT(X)
    RETURN X * X
ENDFUNC

' Another simple function.
FUNC ADD_ONE(X)
    RETURN X + 1
ENDFUNC

' The MAP function. It takes a function reference (FN) and an
' array (ARR), and applies FN to every element of ARR.
FUNC AMAP(FN, ARR)
    ' Create a copy of the array to hold the results.
    RESULT_ARR = ARR

    FOR I = 0 TO LEN(ARR) - 1
        ' Get one element from the array.
        ELEMENT = ARR[I]
        ' Call the passed-in function with the element.
        NEW_VALUE = FN(ELEMENT)
        ' Store the new value back in our result array.
        RESULT_ARR[I] = NEW_VALUE
    NEXT I

    RETURN RESULT_ARR
ENDFUNC

' --- Now, let's use our MAP function! ---
V = IOTA(5)
PRINT "Original Vector V: "; V

' Pass the SQUARE_IT function to MAP
SQUARED_V = AMAP(SQUARE_IT@, V)
PRINT "After MAP(SQUARE_IT@, V): "; SQUARED_V

' Pass the ADD_ONE function to MAP
ADDED_V = AMAP(ADD_ONE@, V)
PRINT "After MAP(ADD_ONE@, V):  "; ADDED_V
