# Ring/Lessons/Functional Programming

< Ring

## 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```