110 likes | 278 Views
CS 341 Programming Language Design and Implementation. Administrative HW #5 is released ― due Monday, 2/17 @ 9pm Functional programming in an imperative world C++11…. I've been claiming Functional Programming (FP) is a good thing One of the arguments for FP : c orrectness
E N D
CS 341 Programming Language Design and Implementation • Administrative • HW #5 is released ― due Monday, 2/17 @ 9pm • Functional programming in an imperative world • C++11… CS 341 -- 10 Feb 2014
I've been claiming FunctionalProgramming (FP) is a good thing • One of the arguments for FP: • correctness • One of the arguments against FP: • performance CS 341 -- 10 Feb 2014
Can we have both? • Yes! • In modern languages like C++, C#, and soon Java • Let's look at C++… • In particular the latest version C++11… CS 341 -- 10 Feb 2014
for (p = &A[0]; p < A+N; ++p) { p->x += x_amt; p->y += y_amt; } • C++ is the epitome of imperative languages • All the imperative features you know and love: variables, memory allocation, pointers, un-typed memory with void *, and side-effects (e.g. see strtok function) • Strong focus on performance • You can write C or C++ CS 341 -- 10 Feb 2014
Recall complete F# program… • what's the average on quiz1? #light let averagescore(fn) = let strings = [ for value in System.IO.File.ReadAllLines(fn) -> value ] let scores = List.map System.Int32.Parse strings let sum = List.reduce (fun x y -> x + y) scores let avg = float(sum) / float(List.length scores) avg [<EntryPoint>] let main argv = let result = averagescore("quiz1.txt") printfn "%A" result 0 // return success [ "100"; "60"; "90"; "88"; "100"; . . . ] [ 100; 60; 90; 88; 100; . . . ] => 4872 => 84.01 CS 341 -- 10 Feb 2014
We can do the same in C++11 & STL (std template lib): • Support for lambda expressions, higher-order functions, … #include <vector> #include <algorithm> ... double averagescore(string fn) { ifstreamfile(fn.c_str()); istream_iterator<string> begin(file); istream_iterator<string> end; vector<string> strings; for_each(begin, end, [&](string line){ strings.push_back(line); } ); [ "100"; "60"; "90"; . . . ] vector is our "list" CS 341 -- 10 Feb 2014
Lambda expressions Closure semantics: [ ]: none, [&]: by ref, [=]: by val, … • Code + data… lambda arguments == parameters • . . .[ ] (int x, int y) { return x + y }; body == code lambda expression CS 341 -- 10 Feb 2014
Closure semantics? • Huh? • A closure is the data needed by a block of code (“close over the environment”) • Closure semantics tells C++ how to perform the closure • by value • by ref • no access What data is needed by lambda expression? What closure semantics are needed per datum? for (inti=0; i<N; i++) { z[i] = a * x[i] + y[i]; } parallel_for(0, N, [ ??? ](int i) { z[i] = a * x[i] + y[i]; } ); CS 341 -- 10 Feb 2014
[ "100"; "60"; "90"; "88"; "100"; . . . ] • Map: [ 100; 60; 90; 88; 100; . . . ] // pre-allocate scores vector for target of map: vector<int> scores( strings.size() ); // map: transform(strings.begin(), strings.end(), scores.begin(), [](string e){ return atoi(e.c_str()); } ); CS 341 -- 10 Feb 2014
[ 100; 60; 90; 88; 100; . . . ] • Reduce: => 4872 // reduce: intsum = accumulate(scores.begin(), scores.end(), 0, [](int x, int y){ return x + y; } ); double avg = sum / (double) scores.size(); return avg; } CS 341 -- 10 Feb 2014
#light open System.IO let averagescore(fn) = let strings = [forvalue in File.ReadAllLines(fn) -> value] let scores = List.map System.Int32.Parse strings let sum = List.reduce (fun x y -> x + y) scores let avg = float(sum) / float(List.length scores) avg [<EntryPoint>] let main argv = let result = averagescore("quiz1.txt") printfn "%A" result 0 // return success #include <vector> #include <algorithm> ... using namespace std; double averagescore(string fn) { ifstreamfile(fn.c_str()); istream_iterator<string> begin(file); istream_iterator<string> end; vector<string> strings; for_each(begin, end, [&](string line){ strings.push_back(line); } ); vector<int> scores(strings.size()); transform(strings.begin(), strings.end(), scores.begin(), [](string e){ return atoi(e.c_str()); } ); intsum = accumulate(scores.begin(), scores.end(), 0, [](int x, int y){ return x + y; } ); return sum / (double) scores.size(); } intmain() { double avg = averagescore("quiz1.txt"); cout << avg << endl; return 0; } CS 341 -- 10 Feb 2014