Ring/Lessons/Functional Programming

Functional Programming edit

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 edit

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 edit

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 edit

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 edit

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 edit

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