val num : int
Full name: Index.num
val str : string
Full name: Index.str
val pi : float
Full name: Index.pi
val circleArea : r:float -> float
Full name: Index.circleArea
val r : float
namespace System
val getTomorrow : today:DateTime -> DateTime
Full name: Index.getTomorrow
val today : DateTime
Multiple items
type DateTime =
struct
new : ticks:int64 -> DateTime + 10 overloads
member Add : value:TimeSpan -> DateTime
member AddDays : value:float -> DateTime
member AddHours : value:float -> DateTime
member AddMilliseconds : value:float -> DateTime
member AddMinutes : value:float -> DateTime
member AddMonths : months:int -> DateTime
member AddSeconds : value:float -> DateTime
member AddTicks : value:int64 -> DateTime
member AddYears : value:int -> DateTime
...
end
Full name: System.DateTime
--------------------
DateTime()
(+0 other overloads)
DateTime(ticks: int64) : unit
(+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : unit
(+0 other overloads)
DateTime.AddDays(value: float) : DateTime
val tomorrow : DateTime
Full name: Index.tomorrow
property DateTime.UtcNow: DateTime
val x : int
Full name: Index.x
val y : int
Full name: Index.y
val add : x:int -> y:int -> int
Full name: Index.add
val x : int
val y : int
val add' : x:int -> y:int -> int
Full name: Index.add'
val add'' : x:int -> y:int -> int
Full name: Index.add''
val addNumbers : x:int -> y:int -> int
Full name: Index.addNumbers
val increment : (int -> int)
Full name: Index.increment
val calculate : f:('a -> 'b -> 'c) -> x:'a -> y:'b -> 'c
Full name: Index.calculate
val f : ('a -> 'b -> 'c)
val x : 'a
val y : 'b
val u : int
Full name: Index.u
val w : int
Full name: Index.w
val a : int
Full name: Index.a
val b : int
Full name: Index.b
val rest : int list
Full name: Index.rest
val aList : 'a list
Full name: Index.aList
val msg : string
Full name: Index.msg
val x : obj
val sprintf : format:Printf.StringFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val y : obj
val eq1 : bool
Full name: Index.eq1
val field1 : string * int
Full name: Index.field1
val field2 : string * int
Full name: Index.field2
val eq2 : bool
Full name: Index.eq2
type Person =
{Name: string;
Age: int;}
Full name: Index.Person
Person.Name: string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
Person.Age: int
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val m1 : Person
Full name: Index.m1
val m2 : Person
Full name: Index.m2
val eq3 : bool
Full name: Index.eq3
Multiple items
module Option
from Microsoft.FSharp.Core
--------------------
type Option<'a> =
| Some of 'a
| None
Full name: Index.Option<_>
union case Option.Some: 'a -> Option<'a>
union case Option.None: Option<'a>
val m : Option<int>
Full name: Index.m
val result : Option<int>
Full name: Index.result
val i : int
F# Functional Programming
Michał Grygierzec
Agenda
- FP in Software Industry
- History
- Motivation
- Concepts
- Insights
- Demo
Functional Programming in software Industry
Functional Programming History
- 1950s - Lisp by John McCarthy (MIT)
- 1960s - APL by Kenneth E. Iverson (Harvard)
- 1970s - ML by Robin Milner (University of Edinburgh)
- 1986 - Erlang
- 1990 - Haskell
- 1996 - OCaml
- 2004 - Scala
- 2005 - F# by Don Syme
- 2007 - Clojure
- 2012 - Elm
- 2014 - Swift
F# History
- 2005 - first stable release (F# 1.0)
- Don Syme - language designer
- Open Source since 2010
- Cross-platform
- fsharp.org - F# official page
My Motivation
- Broaden horizons
- Productivity
- Safety
- Reliability
- Robustness
- Joy
- Peace
Alan Perlis: a language that doesn't affect the way you think about programming, is not worth knowing.
F# Overview
- Functional
- Imperative
- Object-Oriented
- Asynchronous
- Parallel
- Agent model
Type inference
A mechanism used by compiler to deduce what types are used in expressions in a program.
Type inference
1:
2:
3:
4:
5:
6:
|
let num = 7
let str = "F# rocks!"
let pi = 3.14
let circleArea r = 3.14 * r ** 2.
circleArea 1.
|
Type inference - explicit annotations
1:
2:
3:
4:
|
open System
let getTomorrow (today: DateTime) =
today.AddDays(1.)
let tomorrow = getTomorrow DateTime.UtcNow
|
Immutability
- no side-effects
- no mutation of a state
- no modifications of other parts of a program
Immutability
1:
2:
3:
|
let x = 7
// x = x + 1 // WRONG!!
let y = x + 1 // GOOD
|
Currying
... means transforming a function with many arguments,
into a series of functions,
each with only one argument.
All functions in F# are auto-curried by compiler.
Currying
1:
2:
3:
4:
5:
6:
7:
8:
|
let add x y = x + y
let add' x = fun y -> x + y
let add'' =
fun x ->
fun y ->
x + y
|
Partial Application
... means passing to function less arguments
than it originally accepts.
As a result function returns another function,
which accepts remaining parameters.
Partial Application
1:
2:
3:
4:
5:
|
let addNumbers x y = x + y
let increment = addNumbers 1
increment 3
|
Higher Order Functions
Functions which:
accept another function as an input,
or return function as an output.
Higher Order Functions
1:
2:
3:
4:
5:
6:
|
let calculate f x y =
f x y
calculate (+) 3 4
calculate (*) 3 4
|
Pattern Matching
Pattern Matching I
1:
2:
3:
|
let u, _, w = (1, 3, 5)
u
w
|
Pattern Matching II
1:
2:
3:
4:
|
let a::b::rest = [1..10]
a
b
rest
|
[3; 4; 5; 6; 7; 8; 9; 10]
|
Pattern Matching III
1:
2:
3:
4:
5:
6:
7:
|
let aList = []
let msg =
match aList with
| [] -> "empty"
| [x] -> sprintf "one item: %A" x
| [x; y] -> sprintf "two items: %A and %A" x y
| _ -> "many items"
|
Structure Equality I
Structure Equality II
1:
2:
3:
|
let field1 = ("a", 3)
let field2 = ("a", 5 - 2)
let eq2 = field1 = field2
|
Structure Equality III
1:
2:
3:
4:
|
type Person = { Name: string; Age: int }
let m1 = { Name = "Mike"; Age = 22 }
let m2 = { Name = "Mike"; Age = 22 }
let eq3 = m1 = m2
|
Option Type
It is a union of two cases:
- Data is present
- Data is missing
Option Type
1:
2:
3:
|
type Option<'a> =
| Some of 'a
| None
|
Option Type
1:
2:
3:
4:
5:
|
let m = Some 5
let result =
match m with
| Some i -> Some (i * 2)
| None -> None
|
F# Vital Statistics - Most Loved
F# Vital Statistics - Top Paying Tech US
F# Vital Statistics - Top Paying Tech Worldwide
Resources
Summary - F#
- multi-paradigm (FP, OO)
- flexible
- powerful
- functional-first
Summary - F# code
- concise
- clean
- robust
- safe
- expressive
- reusable
- maintainable
F# Developer
Demo
Thank you!
@FSharpWalker