Functional Programming is another development way of thinking compared with object-oriented and procedural Programming, which emphasizes function as the center. Make good use of functional programming ideas, can be of great help and inspiration to our development work, today we will discuss it.
What is functional programming
Let’s use a simple example to illustrate what functional programming is. Let’s say we have a structure like this:
struct Staff {
var firstname: String
var lastname: String
var age: Int
var salary: Float
}Copy the code
The Staff structure defines basic information about an employee, such as name, age, salary, and so on. We declare an array containing our employee information:
let staffs = [ Staff(firstname:"Ming", lastname:"Zhang", age: 24, salary: 12000.0), Staff(firstname:"Yong", lastname:"Zhang", age: 29, salary: 17000.0), Staff(firstname:"TianCi", lastname:"Wang", age: 44, salary: Staff(firstname:"Mingyu", lastname:"Hu", age: 30, salary: 15000.0), Staff(firstname:"TianYun", lastname:"Zhang", age: 25, salary: 12000.0), Staff(firstname:" Meng", age: 24, salary: 14000.0)]Copy the code
Behavioral thinking
Now, we need to find the information of all employees surnamed Zhang (lastName = Zhang). If we use our usual development ideas, we can solve this problem as follows:
var staffOfZhang = [Staff]()
for staff in staffs {
if staff.lastname == "Zhang" {
staffOfZhang.append(staff)
}
}
print(staffOfZhang)Copy the code
This code first declares an array staffOfZhang for Staff instances that meet the conditions. Then we start to go through our STAFFS array. For the staffs instance where lastName equals Zhang, Add them to the staffOfZhang array. This completes our search requirement.
This approach to development can be called a behavioral approach. It focuses on telling programs how to solve problems. For example, we defined where to store the query results and how to iterate through each instance and then read out the qualified instances.
Declarative thinking
There is definitely more than one way to solve a problem, and there is a different way of thinking to solve the problem, which can also be called declarative thinking. We can use Array’s filter method:
let staffOfZhang = staffs.filter { staff in
return staff.lastname == "Zhang"
}Copy the code
This is an example of declarative thinking. The staffs function accepts a closure parameter, and the filter method is called for every STAFFS element using the closure of the passed filter. Depending on the closure’s return value, we decide whether to add this element to our search results as a qualified element (the closure’s return value is true).
In short, we just declare the easy to find rule in the passed closure, which is the return staff.lastName == “Zhang” expression. So we’re done with the whole search operation.
We don’t tell the program how to find elements that meet the criteria, we just declare a rule. The biggest benefit of this is that it reduces the amount of code we need to write, making our code look very concise and easy to understand. This approach is an example of functional programming.
First-Class function
When it comes to functional programming, First Class Function comes up. What the hell is this
To put it simply, a Function like First Class Function can be called simply, assigned to a variable, passed as an argument to another Function, or returned as a value of the Function. On a more detailed description, see this article on Wikipedia: en.wikipedia.org/wiki/First-…
Closures in Swift are First Class, so we can assign them to variables, pass them to functions, return them, and so on. For our example above, we could rewrite it like this:
func filterZhang(staff:Staff) -> Bool {
return staff.lastname == "Zhang"
}
staffOfZhang = staffs.filter(filterZhang)
Copy the code
First Class First Class First Class We first define a filterZhang function and then pass this function as an argument to filter.
As simple as that, this is a demonstration of Swift functional programming.
curry
So, you might be thinking, well, we could define a function like this and pass it as an argument to filter, but what good would it do? No less code than before.
Yes, that’s a crucial question. Listen to the breakdown continue. Another feature of functional programming is Curry. This is also a core concept of functional programming.
Curry is simply a function that generates another function. For a detailed discussion of Curry, please refer to my previous posts:
Advanced application of the Curry feature in the magical Currying Swift
Let’s use a simple example to illustrate the Curry feature. We can rewrite the filterZhang method we just defined:
func filterGenerator(lastnameCondition: String) -> (Staff) -> (Bool) {
return {staff in
return staff.lastname == lastnameCondition
}
}Copy the code
So let’s look at the declaration of the filterGenerator. First it takes a String parameter, and then it returns another function that takes a Staff parameter and returns a Boolean value.
As you can see, the new function filterGenerator is a higher level abstraction of the filterZhang function we defined earlier. FilterZhang will filter all employee instances with lastName equal to Zhang. Using filterGenerator, you can generate any conditional filter function:
let filterWang = filterGenerator("Wang")
let filterHu = filterGenerator("Hu")
Copy the code
As you can see, we pass a different parameter to the filterGenerator and it generates a new filter function based on that parameter. Then we can directly use:
staffs.filter(filterHu)
Copy the code
This call will find all employees whose lastname equals Hu. This is the essence of Curry’s identity. For example, if you’re developing a photo processing APP that has multiple filters that can be stacked on top of each other, using curry will make your development more efficient and your code more robust.
More applications
Let’s look at some more examples. Suppose we now want to save the names of all employees in another array:
var names = [String]();
for staff in staffs {
names.append("\(staff.lastname) \(staff.firstname)")
}
print(names)Copy the code
Let’s see how we can do this functionally:
names = staffs.map{ staff in
return "\(staff.lastname) \(staff.firstname)"
}
print(names)Copy the code
This time we use the Map method, which transforms all the elements of the array according to the rules we specify and generates a new array. All we need to do is declare the transformation rules in the closure. It is also a manifestation of declarative thinking.
For another example, we want to calculate the average salary of all employees:
Var totalSalary = Float(0.0) for staff in staff {totalSalary += staff. Salary} print(totalSalary / Float(staffs.count))Copy the code
Let’s see how we can do this functionally:
let averageSalary = staffs.reduce(0) { total, staff in
return total + staff.salary / Float(staffs.count)
}
print(averageSalary)Copy the code
This time we use Array’s Reduce function, which takes two arguments, the first of which is the initial value, and reduce then operates on each element in turn with that value, passing the calculation to the next element call.
In our case, the idea is to calculate each employee’s base for the average salary, and then add them together to get the overall average salary. Return total + staff. Salary/Float(staffs. Count) So the code reads very clearly and says exactly what we want to do.
conclusion
Here, the basic idea of functional programming is all over. In short, functional programming is characterized by declarative thinking and curry transitive thinking. Its biggest advantage is that it allows us to use elegant syntax to implement previously complex logic. It has also branched out into responsive programming, the popular ReactiveCocoa library that formalizes the Cocoa platform’s implementation of responsive programming. These new programming methods hope to solve our development problems in a more elegant and concise way.
This site articles are original content, if you need to reprint, please indicate the source, thank you.