CS 341 : Programming Languages Functional Programming in a Nutshell Joe Hummel, PhD joe@joehummel.net http://www.joehummel.net/downloads.html Chicago Coder Conference 2017
CS 341 : Programming Languages Example: Standard Deviation Chicago Coder Conference 2017 Joe Hummel, PhD
Can you find the error(s)? int main() { ifstream file; vector<double> values; double value; // input data: file.open("data.txt"); while (!file.eof()) file >> value; values.push_back(value); } // compute mean: double sum = 0.0; int N = values.size(); for (int i = 0; i <= N; i++) sum = sum + values[i]; double mean = sum / N; Std Dev in C/C++ Can you find the error(s)? // diff^2: forall x do (x - mean)^2 for (int i = 0; i <= N; i++) values[i] = pow(values[i]-mean,2); // std dev = SQRT(mean of diffs) for (int i = 0; i <= N; ++i) sum = sum + values[i]; double result = sqrt(sum / N); // output result: cout << "std dev: " << result; cout << endl; return 0; }
Std Dev in F# 2 data.txt [“2”,“4”,“4”,“4”,“5”,“5”,“7”,“9”] file: #light [<EntryPoint>] let main argv = let file = seq { for line in System.IO.File.ReadLines("data.txt") -> line } let values = Seq.map (fun s -> System.Double.Parse(s)) file // let mean = Seq.average values let diffs = Seq.map (fun x -> System.Math.Pow(x-mean, 2.0)) values let result = System.Math.Sqrt( Seq.average diffs ) printfn "std dev: %A" result [“2”,“4”,“4”,“4”,“5”,“5”,“7”,“9”] file: [2.0,4.0,4.0,4.0,5.0,5.0,7.0,9.0] values: [9.0,1.0,1.0,1.0,0.0,0.0,4.0,16.0] diffs: 2
Observation… No variables!!! Work with “values” --- once assigned, they never change Transform values from what you have to what you want Chicago Coder Conference 2017 Joe Hummel, PhD
CS 341 : Functional Programming From Luca Bolognese’s PDC 2008 talk “An Introduction to F#” X i = i + 1 A slide from Luca Bolognese’s talk at PDC 2008. Opening slide, great talk (still available on the web). In essence, while this statement makes sense to most developers, it makes no sense to mathematicians. Why do we continue to work in this imperative style, when it goes against the grain of so much of what we do? Or try to do (e.g. parallel programming)? ==> enter functional / declarative programming as a better way… p = &z *p = … Joe Hummel, PhD
CS 341 : Programming Languages Why functional programming? Many reasons, but the main ones are… More declarative More time declaring what you want, and less time specifying how to do it Lack of side-effects Easier to reason about program correctness Easier to run in parallel on modern multicore hardware Chicago Coder Conference 2017 Joe Hummel, PhD
Functional programming is a state of mind You don’t need a functional language (though it helps) Here’s a functional version of std dev in C++: int main() { . // Seq.average: const auto mean = std::accumulate(V.begin(), V.end(), 0.0) / V.size(); vector<double> V2; V2.resize( V.size() ); // Seq.map: const auto diffs = std::transform(V.begin(), V.end(), V2.begin(), [=](double x){ return pow(x-mean,2.0);}); const auto result = sqrt( std::accumulate(V2.begin(),V2.end(),0.0) / V2.size() ); Chicago Coder Conference 2017 Joe Hummel, PhD
What algorithm does this code perform What algorithm does this code perform? The @ operator concatenates two lists, yielding a new list. [ 30; 18; 78; 42; 12 ] let rec algorithm L = match L with | [] -> [] | e::[] -> [e] | e::L2 -> let (LTE, GT) = List.partition (fun x -> x <= e) L2 (algorithm LTE) @ [e] @ (algorithm GT) Some kind of search Some kind of sort Computes the median (middle value) Reverses the elements of the list
Program-wide type inference with static type checking… One of the benefits… Program-wide type inference with static type checking… let rec quicksort L = match L with | [] -> [] | e::[] -> [e] | e::L2 -> let (LTE, GT) = List.partition (fun x -> x <= e) L2 (quicksort LTE) @ [e] @ (quicksort GT) Chicago Coder Conference 2017 Joe Hummel, PhD
Functional Programming Styles… let rec quicksort L = match L with | [] -> [] | e::[] -> [e] | e::L2 -> let (LTE, GT) = List.partition (fun x -> x <= e) L2 (quicksort LTE) @ [e] @ (quicksort GT) #1 Higher-order… #2 Recursion Chicago Coder Conference 2017 Joe Hummel, PhD
Why F#? Modern syntax as compared to other FP languages Fully-interoperable with .NET library and languages Tool support ― supported by Visual Studio Practical ― offers variables and side-effects when needed 2002: research on F# starts 2005: v1.0 released 2010: v2.0 released, integrated into Visual Studio 2013: v3.0 released
Interop with C# F# is a .NET language Seamlessly interops with other .NET languages Example: Have F# code return a sequence, which appears as IEnumerable to C# Foreach through results var results = FSLibrary.SomeFunction(...); foreach (var result in results) { this.listBox1.Items.Add(result.ToString()); } Chicago Coder Conference 2017 Joe Hummel, PhD
Demo Chicago crime analysis
Demo Asian options pricing simulation
Summary Functional programming requires a new way of thinking Functional programming is: Easier to reason about correctness Easier to parallelize Gaining traction: financials, scientific computing, parallel community Functional programming is not: As efficient as imperative programming (but getting very close) Taught as widely as imperative programming (but getting better) Chicago Coder Conference 2017 Joe Hummel, PhD
Thank you for attending I live here in Chicago, professor & avid sailor Feel free to reach out: Email: joe@joehummel.net Materials: http://www.joehummel.net/downloads.html Microsoft’s main site for F#: http://msdn.microsoft.com/en-us/vstudio/hh388569 Learning F#: MSR (Microsoft Research): http://www.tryfsharp.org/ MSDN mag: http://msdn.microsoft.com/en- us/magazine/ee336127.aspx Chicago Coder Conference 2017 Joe Hummel, PhD
Deterministic resource management Functional languages Object-oriented Static Dynamic Garbage-collected Deterministic resource management Functional