Transcript Slide 1
Functional Programming
Think Differently!!
Functional languages are expressive, accomplishing
tasks using short, succinct and readable code.
Functional languages provide richer ways for
expressing abstractions:
1-1
We can hide the HOW and just focus on the WHAT or
RESULT
Real-world functional programming
Modern programming languages like C# and C++
have incorporated functional programming
paradigm.
Generally this is done through libraries.
It is not necessary to use a functional language to do
functional programming.
1-2
Although it’s much easier to do functional
programming with a functional language.
Characteristics of Functional Programming
Functions as first class objects
Ability to pass functions around as parameters.
No side effects
Everything is done through function return values.
Pass by value parameters only.
Generally typeless, don’t have to declare the type of
variables before using.
Generally have implicit data structure support. You
don’t have to mess with your own data structure.
Let’s get functional
Monday:
C++ algorithms that use functional style.
Function objects
Lambda expressions
Tuesday:
TR1: Functions
Binders
Lab in C++
Next Monday:
Functional programming overview
Intro to F#?
Next Tuesday: Lab in F#?
Let’s get functional in C++
Characteristics of algorithms in C++ standard library:
Functional style, generally don’t use explicit recursion or loops
Implicit loop structure (for loop)
Do something to each element of the vector
Implicit data structure is a vector (array)
In C++ standard library, there is a set of vector-based
algorithms. You can think of a vector as an array. The
algorithms just need a range (begin, end). Note where end is.
begin
end
for_each algorithm
Needs #include <algorithm>
for_each is in the std namespace.
for_each takes a range of values specified with
pointers or iterators.
for_each takes a function pointer or a function
object.
for_each will apply the function to each element
in the range of values.
for_each
void print(int x)
{
cout << x; }
void add5(int &x)
{ x = x+5; }
int array1[5]={1, 2, 3, 4, 5};
for_each(array1, array1+5, add5);
for_each(array1, array1+5, print);
Function Objects
struct someFun{
void operator()(int& x) const
{
x = x+ 43; }
};
int data[10];
someFun aFunObj;
for_each(data, data+10, aFunObj);
for_each(data, data+10, someFun());
accumulate
Accumulate is in <numeric>
It has two forms:
accumulate(begin, end,initValue);
accumulate(begin, end,initValue,
binaryFunc);
The second form of accumulate is a little strange:
accumulate w/ function
accumulate(beg, end, initValue,
binaryFunc)
initValue = binaryFunc(initValue,
eachValueInRange)
int data[10];
int result = accumulate(data, data+10,
1, binaryFunc);
int
{
binaryFunc (int sum, int value)
return
sum * value; }
data
Transform
There are two forms of transform:
transform(sourceBegin, sourceEnd, destination,
unaryFunc);
// apply unaryFunc to each element in source range, write results to
// sequence starting at destination
transform(source1Begin,
source1End,source2Begin, destination,
binaryFunc);
// same as above, but work with two source ranges
transform() can modify an existing sequence or can
make a new one.
To modify an existing sequence, make destination the
same as sourceBegin.
Transform: Single Source
int data[10];
int changeData(int &x)
{
return x*2; }
transform(data, data+10, data,
changeData);
Transform: Two Sources
int
int
int
int
{
data1[10];
data2[10];
data3[10];
addThem(int x1, int x2)
return x1+x2; }
transform(data1, data+10,
data2,data3, addThem);
Transform: Two Sources w/ function
object
int data1[10];
int data2[10];
bool data3[10];
Struct magicSum
{ int sum;
magicSum(int x): sum(x){}
bool operator()(int x, int y)
{ return x+y == sum; }
};
transform(data1, data+10, data2,data3,
magicSum(37));