What is Functional Programming from a Student’s Point of View part-II

Çağıl ilhan Sözer
4 min readJan 22, 2021

--

Hello again, i’m still trying to learn functional programming consepts and Scala. It’s quite challenging to learn new programming paradigm and trying to change my entire mindset. You can read part I in here.

So, this is my notes and what i understand about these consepts. I hope you like it enjoy !:)

Currying

If we don’t know how many argument we need in a function, what should we do ? This is the question and currying the answer.
Currying Function is a function that takes one argument and returns a new function which takes also one argument.

def add(x:Int,y:Int):Int = x+ycurrying version =>def addWithCurrying(x:Int) = (y:Int) => x+y

now we can call this function

without currying:
add(3,5) == 8
addWithCurrying(3)(5) == 8
or
val curry = addWithCurrying(3)
println(curry) // <function1>println(curry(5)) // 8

Both of these function return the same value, but now we can call this function with only one parameter. And we can save the return value.

def addCurry(x:Int)(y:Int) = x+y

We can define the currying function like this way too. And if we want to call we can simply type

val curry = addCurry(3)_ //  <function1> 
The underscore is a placeholder in this case.

FUNCTION LITERAL

It’s an alternative syntax for function definition.

(a:Int, b:Int) => a*b

We can define a multiply function like this.

val multiply = (a:Int, b:Int) => a*b

Function literals are anonymous,
but we can assign this function to a value and use it later.

This is usefull in High order functions, Like in scala implementation, fold function



def foldLeft[B](z: B)(op: (B, A) => B): B = {
var result = z
this foreach (x => result = op(result, x))
result
}

op is a function literal in here, and this is an example for high order functions. What is high order functions?
Let’s get into it.

HIGH ORDER FUNCTIONS

High order functions take other functions as parameters or return a function as a result.
I’ve followed the scala-tour example and try to understand what’s going on!

val salaries = Seq(20000, 70000, 40000)
val doubleSalary = (x: Int) => x * 2
val newSalaries = salaries.map(doubleSalary) //

In this example, There is a salaries value which is a sequence.
Double salary is a function that multiplies the element by 2 (double salary is a function literal)
Map function take another function as parameter, and applying this function to salaries => neWSalaries

Map function is an example for high order functions.

def urlBuilder(ssl: Boolean, domainName: String): (String, String) => String = {
val schema = if (ssl) "https://" else "http://"
(endpoint: String, query: String) => s"$schema$domainName/$endpoint?$query"
}
val domainName = "www.example.com"
def getURL = urlBuilder(ssl=true, domainName)
val endpoint = "users"
val query = "id=1"
val url = getURL(endpoint, query)

In this example, urlBuilder takes two parameter, and Return another (String,String) => String functions.
This is because urlBuilder take the ssl parameter for find out if this site is safe or not. if it’s safe, the url start with the https else http. Also url take the domain name, In this way, we can build any url we want. like https://medium.com/ .
But in medium there are so many url. What if you want to search me in medium ? (https://medium.com/searchq=%C3%A7a%C4%9F%C4%B1l%20ilhan%20s%C3%B6zer , we can see the searching endpoint after .com)
Every request in medium(or any webiste), start with the same part (https://medium.com/) after that every request reach diffrent endpoint.
Thanks to high order functions, getURL value return a function that we can changing our endpoint or query later. This is a great case to understand how high order functions works.

PARTIALLY APPLIED FUNCTIONS

We can define functions with multi parameter group like this

def multiply(x:Int,y:Int): Int = x*y
multiply(3,12) // 36

This isn’t unusual thing. But in Functional programming word there is partially applied functions which we can call a function
just give some arguments. Functions keep these argument and return a new function which wait for remaining arguments.

We can call multiply function like this way => 
multiply(2,_,_) or multiply(_,2,_)
def multiply(x:Int, y:Int,z:Int): Int = x*y*z
val x = multiply(_,0,_)
val z = x(2,_)
val y = z(1)
println(x,z,y) ///(<function2>,<function1>,2)

Above example, we called multiply with just one argument and give the other arguments later.
I think output of x and z show how many functions remaining in the x value.
When there is no function left (or we passed all the argument that function needs) multiply works and return the x*y*z.

Also We can use partially applied function in urlBuilder example

val safe= urlBuilder(true,_)
val notSafe = urlBuilder(false,_)
val domain = "www.medium.com"
val anotherDomain = "www.another.com"
safe(domain)(endpoint,query)
notSafe(anotherDomain)(endpoint,query)

Again we passed few argument, first argument domain complete the urlBuilder function and this function return another function which takes 2 parameter.

Thanks who read all of my notes i hope you enjoyed! Please feel free to give me any feedback or ask any question. Let’s see you guys in part 3 :)

--

--