Professional Documents
Culture Documents
PROGRAMMING
A. A. Datti
COURSE OUTLINE
1. Introduction to Structured Programming
2. What is functional programming?
3. Functional vs. Object-oriented programming
4. Functions
5. Understanding your application’s control flow
6. Method chaining and Function chaining
7. Reasoning about your code
8. Learning to think recursively
SWE4205 - STRUCTURED PROGRAMMING 2
FUNCTIONS
FUNCTIONS
In functional programming, functions are the basic units of work, which
means everything centers around them.
Because FP works a lot like math, functions are meaningful only when they
produce a usable result (not null or undefined); otherwise, the assumption is
that they modify external data and cause side effects to occur.
FUNCTIONS
We can distinguish between expressions (functions that produce a value)
and statements (functions that don’t).
JavaScript functions have two important characteristics that are the bread
and butter of its functional style: they are first-class and higher-order
FUNCTIONS AS FIRST-CLASS
CITIZENS
In JavaScript, the term first-class comes from making functions
actual objects in the language — also called first-class citizens.
The constructor takes the set of formal parameters, the function body, and the
new keyword, like so:
HIGHER-ORDER FUNCTIONS
Because functions behave like regular objects, you can intuitively expect that they
can be passed in as function arguments and returned from other functions. These are
called higher-order functions.
The applyOperation function below takes two arguments and applies any operator
function to both of them:
HIGHER-ORDER FUNCTIONS
In the next example, the add function takes an argument and returns a function that, in turn,
receives a second argument and adds them together:
Because functions are first-class and higher-order, JavaScript functions can behave as values,
which implies that a function is nothing more than a yet-to-be-executed value.
HIGHER-ORDER FUNCTIONS
Higher-order functions help you get shorter, more concise, and easier to understand code. The
following are some HOF available in JavaScript:
•reduce() to apply an operation to a whole array, reducing it to a single result
•map() to transform one array into another by applying a function to each of its elements
•flat() to make a single array out of an array of arrays
•forEach() to simplify writing loops by abstracting the necessary looping code
•filter() to pick some elements from an array
•find() and findIndex() to search for elements that satisfy a condition
•every() and some(), to check an array for a Boolean test
REDUCING AN ARRAY TO A
VALUE
It is common to loop through an array, performing an operation to
produce a single value (maybe the sum of all the array values) as a
result.
•The initialization and handling of the result values are also done
implicitly.
•Unless you work really hard at being impure and modifying the
original array, your code will be side effect free.
SUMMING AN ARRAY
Basically, to reduce an array, you must provide a dyadic function (a
function with two parameters) and an initial value.
Initially, the function will be applied to the provided initial value and
the first element of the array. So for us, the initial value we have to
provide is a zero, and the first result will be the first element itself
(plus zero).
SUMMING AN ARRAY
Then, the function will be applied again, this time to the
result of the previous operation, and the second element
of the array, and so the second result will be the sum of
the first two elements of the array.
Instead of having to write out the loop, initializing a variable to hold the result of the
calculations, and going through the array doing the sums, you just declare what
operation should be performed.
This is what is meant by programming declaratively, focusing on what rather than how.
CALCULATING AN AVERAGE
How do you calculate the average of a list of numbers?
For example, you might transform numbers into strings, strings into
numbers , or maybe numbers to numbers:
Second, you don't even have to access the original array or the index
position, even though they are there for you to use if you really need
them.
We can map each element of the array to just its latitude, and we would then
have an appropriate input for average().
EXTRACTING DATA FROM
OBJECTS
Mapping an array to extract data is powerful, but you must be careful. Let's
now look at a case that seems right, but produces incorrect results!
WORKING WITH RANGES
We want a range(start,stop) function that generates an array of numbers, with
values ranging from start (inclusive) to stop (exclusive):
Why fill(0)? All undefined array elements are skipped by map(), so we need to fill
them with something or our code will have no effect.
WORKING WITH RANGES
We can redo our factorial function by applying range() and then reduce().
The idea of this is to simply generate all the numbers from 1 to n and then multiply
them together:
MORE GENERAL LOOPING
The preceding examples that we've seen simply loop through arrays, doing some
work.
However, sometimes you need to do a loop, but the required process doesn't really
fit map() or reduce().
For instance when you want to perform an action within the loop but not return
anything at the end of the loop.
So what can be done in such cases? There is a forEach() method that can help.
MORE GENERAL LOOPING
If you use the range() function that we defined previously, you can also perform
common loops of the for(i=0; i<10; i++) variety.
We might write yet another version of factorial (!) using that:
LOGICAL HIGHER-ORDER
FUNCTIONS
Up to now, we have been using higher-order functions to produce new results,
but there are also some other functions that produce logical results by
applying a predicate to all the elements of an array
Using these functions implies that your code will become shorter: you can,
with a single line of code, get the results corresponding to the whole set of
values.
FILTERING AN ARRAY
A common need that we will encounter is to filter the elements of an array
according to a certain condition.
The filter() method lets you inspect each element of an array in the same
fashion as map().
The difference is that instead of producing a new element, the result of your
function determines whether the input value will be kept in the output (if the
function returned true) or if it will be skipped (if the function returned false).
Also similar to map(), filter() doesn't alter the original array, but rather
returns a new array with the chosen items.
FILTERING AN ARRAY
Always return something from your predicate:
By the way, given that the filtering operation produced yet another array, if you just
wanted the accounts IDs, you could get them by mapping the output to just get the
ID field. And if you didn't care for the intermediate result, a one-liner would have
done as well:
SEARCHING AN ARRAY
Sometimes, instead of filtering all the elements of an array, you want to find
an element that satisfies a given predicate (logical relation).
There are a couple of functions that can be used for this, depending on your
specific needs:
find() searches through the array and returns the value of the first element
that satisfies a given condition, or undefined if no such element is found
findIndex() performs a similar task, but instead of returning an element, it
returns the index of the first element in the array that satisfies the condition,
or -1 if none were found
SEARCHING AN ARRAY
Going back to the geographic data we used earlier, we could easily find a given
country by using the find() method.
For instance, let's get data for Brazil ( "BR"); it just takes a single line of code:
SEARCHING AN ARRAY
If we wanted the position of the country in the array, we would have used
findIndex():
HIGHER-LEVEL PREDICATES –
SOME, EVERY
The last functions we are going to consider greatly simplify going through arrays to
test for conditions:
every(), which is true if and only if every element in the array satisfies a given
predicate
some(), which is true if at least one element in the array satisfies the predicate
For example, we could easily check our hypothesis about all the countries having
negative coordinates:
ASSIGNMENT
You run a company and you just decided to give all your employees a N10,000 raise. Write the program in OOP
style and in Functional style?
In OOP:
Create Employee class that initializes with name and salary, and has a change salary instance method
Create instances of employees
Use each method to change the salary attribute of employees by +10,000
In FP:
Create employees array, which is an array of arrays with name and corresponding salary
Create a change_salary function that returns a copy of a single employee with the salary field updated
Create a change_salaries function that maps through the employee array and delegates the calculation of the new
salary to change_salary
Use both methods to create a new dataset, named ‘happier employees’
END