Introduction to Functional Programming

Ross Murray

  • Graduated from Southeastern in 2011
  • First programmed in GW-BASIC on a Tandy 1000
  • I like
    • colors
    • games
    • programming
    • people
  • I have no idea what I'm doing
  • Please interrupt with questions

Scope

  • Broad survey of functional programming
  • Examples
  • Relate topics to C#
  • Practical applications

What is functional programming?

Two things:

  • A programming paradigm
  • A type of programming language

Programming paradigms

A programming paradigm is a style of programming, like a movie genre

  • Imperative
  • Object-oriented
  • Declarative
  • Event-driven
  • Contstraint programming
  • Agent-oriented
  • Reactive


They're not always mutually exclusive

Imperative programming


  • A sequence of statements
  • State and control flow
    • Variables, conditionals, loops
  • Procedures
  • Basic abstraction over machine code
int i = 10;
int s = 8;
int p = 29;

while(i > 0) {
p = p + s;
if(i < 5) s = i +4; i = i - 1;
} memrcv(p);

Object-oriented programming


  • Objects, with state and behavior
  • Message-passing
  • Polymorphism and dynamic dispatch
  • Information hiding
interface Animal
Speak()
Eat() class Dog
sustained: boolean
Speak(): "Woof!"
Eat(): sustained = true

fn main()
Animal a = new Dog()
a.Speak()

Declarative programming


  • Contrasted with imperative programming
  • Declare truths instead of giving instructions
  • Say what you want, not how to get it
  • Minimize side-effects


SELECT Book.title AS Title,
COUNT(*) AS Authors
FROM Book
JOIN Book_author
ON Book.isbn = Book_author.isbn
GROUP BY Book.title;

Functional programming paradigm


  • A subset of declarative
  • Core tenets:
    • Higher-order functions
    • Referential transparency
    • Immutability
    • Powerful type systems


let SumOfSquares n = 
[1..n]
|> List.map (fun x -> x*x)
|> List.sum

SumOfSquares 5

Core concepts


Quick primer on some terms

  • Expressions
  • Functions
  • Type systems
  • First class functions

What's an expression?


Something which can be evaluated to produce a value.

 1099                       // int
String.Format("{0}!", age) // string
x => x + 10 // Func<int, int> (length > 0) // bool

Statements are expressions which either evaluate to void, or whose value is ignored by using a semi-colon.
 var x = 400;               // 400, but ignored
 Console.WriteLine("void"); // void

What is a function?


A "pure" function is a map of inputs to outputs


No side effects. Just output.

Type systems


A set of rules imposed on a program. The program is not correct if the rules are violated

  • Static vs Dynamic
  • Structural vs Nominal
  • You can put anything in the type system
    • Linear / Unique types
    • Lifetime

First-class functions


Treating functions like any other value

  • Assign a function to a variable
  • Pass a function to another function
  • Return a function from a function

let double n = n * 2
let ten = double 5
let twenty = double ten

C# function types


Action and Func are types in C# that describe code
Func<A,R> takes an A, returns an R
Action<A,B> takes an A and B, returns void

public double Whatever(string s, int i) { ... }

Func<string, int, double> foo = Whatever;

Action<string> bar = Console.Writeline;

Func<string, string> = File.ReadAllText;

Higher order functions


Fancy term for a function that either:

  • Takes a function as a parameter
  • Returns a function

Example

students.Select(x => x.Name);

Signature of Select
IEnumerable<U> Select<T,U>(this IEnumerable<T> source, Func<T,U> map)

Referential transparency


An expression is referentially transparent if replacing the expression with its evaluation does not alter the program.

 cos(1.2)               // 0.362357754476674
 "foo" + "bar"          // "foobar"
 "Mixed Case".ToLower() // "mixed case"


Given the same inputs, it must always produce the same output, with no side-effects.

 File.ReadAllText(@"C:\temp\foo.txt")  // reads from disk

Referential transparency


No:

  • Altering function arguments
  • Any sort of I/O (disk, network)
  • Accessing class members
  • Changing a static variable
  • etc

Immutability

Means things don't change (mutate)

Immutability is a key tool for simplicity

String s = "one";
s.ToLower();   // does nothing.
DateTime d = DateTime.UtcNow - TimeSpan.FromMinutes(200);

Some immutable types in C#

  • string
  • DateTime
  • Guid
  • int

Some FP languages

  • Clojure
    • dynamically typed
    • focus on immutability and meta-programming
    • Lisp syntax
    • main impl: JVM, javascript
  • Haskell
    • "academic" language
    • focus on referential transparency and types
    • de facto lingua franca
    • main impl: native

Some FP languages

  • Scala
    • Java++
    • multi-paradigm
    • Netflix, Twitter
    • main impl: JVM
  • F#
    • multi-paradigm
    • main impl: CLR
  • Erlang
    • dynamically typed
    • focus on concurrency and stability
    • whatsapp, facebook chat
    • main impl: Erlang VM

Common FP language tools


  • Algebraic data types / tagged unions
  • Pattern matching
  • Monads
  • Tuples
  • Type inference
  • Anonymous functions

Algebraic data types


type Shape {
  Circle(Point, float),
  Rectangle(Point, Point)
}

Discriminated union / tagged union

Alternative to class hierarchies

Pattern matching


let rec factorial n =
match n with
| 0 -> 1
| _ -> n * factorial (n - 1)


Kind of like a powerful switch statement

Used to destructure types (ADTs, tuples)

Compile-time checking

Can have guards and wildcards

Pattern matching


public float Area(Shape sh) {
  match sh {    Circle(_, radius) => PI * radius * radius,    Rectangle(Point{x,y}, Point{x2,y2}) => (x2 - x) * (y2 - y)  }}

Tradeoffs with class hierarchies
Easier to add functionality, harder to add new types

Monads


C# examples: Nullable<T>, IEnumerable<T>


A design pattern for abstracting some functionality over a type


Wraps the type and provides indirect access via functions


Common abstraction method in FP languages

Functional programming


composing mostly pure functions


in a declarative style


often using immutable values


and a rich type system

What's the point?


Simple things that compose well

Easy to write reusable code

Easy to test and reason about

Especially effective in the small scale

Realistic takeaway


  • Simplicity promotes correctness and readability
  • Most complexity hides between components, or in hidden assumptions
  • Pure functions and immutability enforce simple APIs and interactions
  • Let the type system catch errors whenever possible
  • Don't be afraid to use functions as values if it simplifies your API

Structuring C# (opinions)


  • Separate data and behavior.
  • Most code can go in "service" classes which have no fields or properties, only pure functions (maybe a logger).
  • Most data types don't need any methods or private members.
  • Classes that need to store state can usually be limited to just a few private members. Separate unrelated functionality.
  • Avoid inheritance whenever possible, especially for deduplication.

Structuring C# (opinions)


  • Lean heavily on LINQ
  • Pretend things are immutable, especially containers
    • Make new things instead of changing existing ones
  • Single responsibility principle, dependency injection
  • Be pragmatic. Don't rush out and change everything

introduction to functional programming

By Ross Murray

introduction to functional programming

  • 1,723