====================== 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 .. index:: pair: Functional Programming; Pure 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: .. code-block:: none 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: .. code-block:: none aList 1 2 3 4 5 aList2 1 4 9 16 25 .. index:: pair: Functional Programming; First-Class Functions 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: .. code-block:: none Call Variable([Parameters]) Example: .. code-block:: none 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: .. code-block:: none before test2() Message from test! Message from test2! after test2() Message from test! .. index:: pair: Functional Programming; Higher-order Functions Higher-order Functions ====================== Higher-order functions are the functions that takes other functions as parameters. Example: .. code-block:: none 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: .. code-block:: none 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! .. index:: pair: Functional Programming; Anonymous and Nested Functions Anonymous and Nested Functions ============================== Anonymous Functions are functions without names that can be passed as parameters to other functions or stored in variables. Syntax: .. code-block:: none Func [Parameters] { [statements] } Example: .. code-block:: none 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: .. code-block:: none hello Sum : 6 wow! Message from f1 hello world hello world hello world Example: .. code-block:: none 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: .. code-block:: none 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: .. code-block:: none 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: .. code-block:: none hello how are you? hello 0 0 1