This talk is about functional programming in general and F# in particular.
This man, Alonzo Church, invented Lambda Calculus which is a formal theory for functionality.Many of the languages depicted here represents family of languages so for example LISP has a number of derivatives such as CLISP, Scheme, Clojure and ML has Standard ML, CAML, OCAML and F#LISP (Conditional expr, Cons cells, Garbage collection, S-expressions)APL doesn’t rely on lambda expressionISWIM (if you see what I mean). It’s interesting to see that it could’ve been a description of F# (infix, let where, Indentation). Invented by Peter Landin (also the inventor of the first VM and the expression ’syntactic sugar’)ML uses Hindley-Milner type inference and parametric polymorphism, abstract data typesFP created by John Backus (creator of Fortran) who gave the ”Can Programming Be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs”Miranda has list comprehensions and possibility to convert infix operators to functionsOcaml is multi-paradigm in that it combines OO and FuncScalaF# is a Ocaml dialectClojure is a LISP dialect running on JVM and CLR with built in support for concurrency
In declarative programming style focus is on the logic (the what) and control is handed to the language.In imperative programming style both control and logic is the responsibility of the programmer.Side effects = state changes may occurReferential transparency = an expression may be substituted by its value and it won't affect the end result.Ref. http://www.csc.liv.ac.uk/~frans/OldLectures/2CS24/declarative.html#detail
So what’s wrong with imperative programming?Due to mutability, it takes an inhumanly amount of DISCIPLINE to make STATE changes EXPLICIT.
Some arguments raised against fp, however:The leap from Java/C# to Scala/F# isn’t that big; there’s a different way of thinking but devs like to think.Interop/few libs is not a valid argument for Scala/F#Customer do care about getting new functionality fast and which is robust.
There are many good reasons: More concise and readable code Fewer bugs due to immutability Easier to reason about code due to referential transparency and therefore easier to prove correctness which leads to better optimizations by compiler Programmer effeciency Easier to parallelize etcBut apart from these reasons: It's fun! It bends your mind into thinking differently (if you come from the oo/imperative world)One of the strongest benefits is that it lends it self to modular programs through composability. Here are some examples of how we can compose functions using just a few simple primitives.
F# is a pragmatic language - "write simple code to solve complex problems“Interop with .NET’s CLI makes it very powerfulThe fact that a large company supports it makes it a good choice
Strong, static and parametric polymorphic type systemMulti-paradigmCurrent version 3.0
C#-programmers sometime find F#’s syntax hard to decipher...This is a rather complex function in C# with pretty low readability, somewhat due to strange formatting, but mainly due to ”noise” from type annotations. It calculates the difference between two tree structures
Remove type annotations...
Pattern matching and tuples
Remove brackets, semi-colons and curly braces
Add F# keywords and create expression
let denotes binding value to variable, i.e. not assignment (remember immutability)Function definition using letfun is the keyword for lambda function
Nested function definitionsRecursive function
In functional languages algebraic data types are often used as data carriers (all CLI types are of course available as well). They are types composed by other types.The two most common classes are the sum type and the product type.
A union is a sum type that takes the shape of one of its composed types.It can be compared to a object hierarchy in the OO paradigm and in fact, the compiler creates a base class and subclasses for each construct.The correspondance to method dispatching is done by using pattern matching in F#
Union types can be recursively definded.
In C# for example a returned reference object might be null but it’s easy to forget to check this case. When option type is used in a match expression then the compiler issues a warning if the None-case isn’t covered.What is returned in the above case when id not found?
One of the most central types in FPSemantically eqvivalent to the sum of union and a product type. In F# Nil is  and Cons (hd*tl) is hd::tl
Lists can be constructed in several different ways: by semi-colon separated listed values, using the cons operator, through sequence expression
Functions as values (first-class functions) makes it possible for a function to take other functions as an arguments and/or return a function. Such functions are called higher-order functions.Higher-order functions allows us to build abstractions and makes it possible to write declarative code since the control structure is hidden in these functions. Examples are map, fold, reduce, filter etc.
map is an reusable abstracted hof that hides the control structure and lets us instead focus on the logic of our program
Declarative way of using the hof map, i.e. ”map this function to the list l”
Pipelining lets you pipe data in the ”x-direction” instead of in the ”z-direction” which makes it more readable.It also benefits type inference
Is functional programming the future? I hope I’ve managed to show that functional programming meansSimpler codeMore solid programsFUN
Functional programming in F# The Why, What and How
Back in the days... ISWIM λ 1958 LISP 1966 1930-ish 1962 APL 1973 ML 2007 1977 FP Clojure2005 F# 1986 Erlang 2003 Scala 1988 Haskell Ocaml 1996
Some definitionsProgram Data - Logic - ControlDeclarative Logic - Referential transparencyImperative Logic - Control - Side effects
Functional programming language DeclarativeFirst class λHigher-Order ImmutabilityFunctions
The PAIN of imperativenessScrewupability Shared mutable states
Why not functional programming? • Too low dev replacability • Legacy code not functional • Bad interop, few libs • Devs find it too hard • Customers don’t care anyway
F# data types - Uniontype Shape = | Circle of float | Rectangle of float * float | Triangle of float * float
F# data types – Recursive union type BinTree = | Leaf of int | Node of BinTree * BinTree
F# data types - Option type Option<a> = | Some of a | None
F# data types - Option public Document getDocByID(int id); VSval getDocByID : int -> Document option
F# data types - Optionlet res = match getDocByID id with | None -> …handle not found… | Some(d) -> …do something with d…
F# data types - Listtype List<a> = | Nil | Cons of a*List<a> Nil + a*List<a>
F# data types - Listlet l1 = ["a"; "list"; "of"; "strings"]let l2 = "a"::"consed"::"list"::let l3 = [1..42]let l4 = [for i in l3 -> i*i]
Higher-order functionslet rec double l = match l with |  -> List.empty | h::t -> h*2::double t
Higher-order functionslet rec length (l:string list) = match l with |  -> List.empty | h::t -> h.Length::length t
Higher-order functionslet rec map f l = match l with |  -> List.empty | h::t -> f(h)::map t
Higher-order functionsmap (fun x -> 2*x) listmap (fun (x:string) -> x.Length) list
Pipelining h(g(f(x))) VS x |> f |> g |> hPipeline operator
Function composition let f x = h(g(x)) VS let f = g >> h Composition operator
Function compositionlet double_then_sum = List.map ((*)2) >> List.reduce (+)
Synchronous -> Asynchronouslet getData (url:string) = let r = WebRequest.Create(url) let resp = r.GetResponse() use stream = resp.GetResponseStream() use reader = new StreamReader(stream) let data = reader.ReadToEnd() data
F# 3.0• Type Providers• Query Expressions• Triple-quoted strings
SummaryFunctional programming lets you Focus on the problem and less on noise Write consice and readable code Create composable programsF# gives you Access to the .NET framework Cross-platform Multiparadigm for solving real-world problems
So...Complex vs Simple Spaghetti vs Composability λ = Future? Headache vs Fun Lots of plumbing vs Logic
Jaywaychristian.email@example.com@chribbenFunctional Programming Sthlm User GroupJayway seminarsØredev