Functional Programming

In previous chapters we learned about Functions and Recursion.

In this chapter we are going to learn about more Functional Programming (FP) concepts like

  • Pure Functions

  • First-class functions

  • Higher-order functions

  • Anonymous and nested functions.

  • Equality of functions

Pure Functions

We can create pure functions (functions that doesn’t change the state) by the help of the assignment operator to copy variables (Lists & Objects) by value to create new variables instead of working on the original data that are passed to the function by reference.

Example:

Func Main
        aList = [1,2,3,4,5]
        aList2 = square(aList)
        see "aList" + nl
        see aList
        see "aList2" + nl
        see aList2

Func Square aPara
        a1 = aPara              # copy the list
        for x in a1
                x *= x
        next
        return a1               # return new list

Output:

aList
1
2
3
4
5
aList2
1
4
9
16
25

First-class Functions

Functions inside the Ring programming language are first-class citizens, you can pass functions as parameters, return them as value or store them in variables.

We can pass/return the function by typing the function name as literal like “FunctionName” or :FunctionName for example.

We can pass/return functions using the variable that contains the function name.

We can call function from variables contains the function name using the Call command

Syntax:

Call Variable([Parameters])

Example:

Func Main
        see "before test2()" + nl
        f = Test2(:Test)
        see "after test2()" + nl
        call f()

Func Test
        see "Message from test!" + nl

Func Test2 f1
        call f1()
        See "Message from test2!" + nl
        return f1

Output:

before test2()
Message from test!
Message from test2!
after test2()
Message from test!

Higher-order Functions

Higher-order functions are the functions that takes other functions as parameters.

Example:

Func Main
        times(5,:test)

Func Test
        see "Message from the test function!" + nl

Func Times nCount,F

        for x = 1 to nCount
                Call F()
        next

Output:

Message from the test function!
Message from the test function!
Message from the test function!
Message from the test function!
Message from the test function!

Anonymous and Nested Functions

Anonymous Functions are functions without names that can be passed as parameters to other functions or stored in variables.

Syntax:

Func [Parameters] { [statements] }

Example:

test( func x,y {
                        see "hello" + nl
                        see "Sum : " + (x+y) + nl
               } )

new great { f1() }

times(3, func { see "hello world" + nl } )

func test x
        call x(3,3)
        see "wow!" + nl

func times n,x
        for t=1 to n
                call x()
        next

Class great
        func f1
                f2( func { see "Message from f1" + nl } )

        func f2 x
                call x()

Output:

hello
Sum : 6
wow!
Message from f1
hello world
hello world
hello world

Example:

Func Main
        aList = [1,2,3,4]
        Map (aList , func x {
                                return x*x
                            } )
        see aList
        aList = [4,9,14,25]
        Map(aList, :myfilter )
        see aList
        aList = [11,12,13,14]
        Map (aList , func x {
                if x%2=0
                        return "even"
                else
                        return "odd"
                ok
        })
        see aList

Func myfilter x
        if x = 9
                return "True"
        else
                return "False"
        ok

Func Map aList,cFunc
        for x in aList
                x = call cFunc(x)
        next

Output:

1
4
9
16
False
True
False
False
odd
even
odd
even

Equality of functions

We can test if function = function or not using the ‘=’ or ‘!=’ operators

Example:

f1 = func { see "hello" + nl }

f2 = func { see "how are you?" + nl }

f3 = f1

call f1()
call f2()
call f3()

see (f1 = f2) + nl
see (f2 = f3) + nl
see (f1 = f3) + nl

Output:

hello
how are you?
hello
0
0
1