You are on page 1of 37

Dmitri Nesteruk

dmitrinesteruk @ gmail.com
http://spbalt.net
a programming paradigm that
treats computation as the evaluation
of mathematical functions and
avoids state and mutable data
Wikipedia
Higher-order functions
i => j => f(j)
Pure functions
Immutability
No side eects
(Tail) recursion
let f(x) = ; f(x-1);
Pattern matching
Math
Probabilistic models
Symbolic processing (parsing/lexing)
Symbolic dierentiation
Circuit verification
Multi-paradigm language in .NET stack
Functional
Imperative
Performance similar to C#
Interactive console
Support in Visual Studio
Debugger
Editor
Mono support
#light
printfnHello,F#!

#light
Light syntax cuts down on ceremony when
writing code
Indentation instead of begin/end
Use of in,done keywords not required
No semicolons
Currently mandatory will be default in future
printfnHello,F#
Writes a line to the console
A top-level binding (like a global function)
Part of FSharp.Core
Referenced implicitly
Appears in a generated _main()
Can Go To Definition
Can do it with a function

letsayHello=
printfnHello,F#!
sayHello

Or pass a parameter

letsayHellos=
printfns
sayHello"Hello,F#!"
Application operator |> (forward pipe)

letsayHellos=
s|>printfn//sameasprintfns

Explicit types

letlengtha=a.Length;//notok
letlength(a:string)=
a.Length//ok
Recursive definition

letrecfactorialn=
ifn<=1then1
elsen*factorial(n1)

Mutual recursion

letrecfuncAx=1+funcB(x)
andfuncBx=1funcA(x)
One statement per line, use in for more
letpowerOf4x=
lety=x*xiny*y
No implicit conversions
letGetXNamexname=
XName.op_Implicit(xname)
Aggressive strong typing
leto:obj=test;//fails
leto=boxtest;//ok
Mutability must be explicit
mutable keyword
variable<valueto assign
Clever switch statement
Can match values of any type

letmatchMex=
matchxwith
|1>printfn"one"
|2>printfn"two"
|_>printfn"somethingelse"

Cannot bind same pattern element twice


Cannot match (x, x)
Can match (x, y) when x = y
Tuple
Option value
Array
Sequence
List
Contains several values of any types
No more Pair<T,U>etc. classes

letsumAndProductab=
(a+b,a*b)

let(s,p)=sumAndProduct23
printfn"%d%d"sp

Tuples use comma ,


Other structures use semicolon ;
null is typically not used with F# types
Presence or absence can be discriminated with
an option value, which is
None
Someof'a
Use pattern matching

matchxwith
|Some(name)>printfnname
|None>printfnanonymous
Your typical CLR array

letpeople=[|
john;
jane;
jack
|]

people.Length
yields 3
Enumerable values
leta=seq[1;2;3]
letb=seq{foriin1..10>(i*i)}
Lazy-inited
seq{1..10000000}
Step
seq{1..2..10}
yields 1, 3, 5, 7, 9
Strings are char sequences
printfn"%d"(Seq.length"Hello")
Iterated with for .. in .. do
foriinmySeqdoprintfn%di
Linked list of values

[1;2;3]

Has head and tail


Head is the first element
Tail is everything else
[] is the empty list
[1, 2, 3] has length of 1:)
leta=[1;2;3]
Head = 1
Tail = [2;3]
letb=0::a
[0;1;2;3]
letc=a@b
[1;2;3;0;1;2;3]
letrecsumAllmyList=
matchmyListwith
|h::t>head+sumAll(t)
|[]>0

letrecnonZeromyList=
matchmyListwith
|0::t>1::nonZerot
|h::t>h::nonZerot
|[]>[]

letrechtmlDecodetext=
matchtextwith
|&::g::t::;::tail>
>::htmlDecodetail//andsoon
A non-exhaustive match will throw a
MatchFailureException

Patterns can be grouped


matchpersonwith
|a::(b::cassubGroup)>
matchsubGroupwith
Anonymous functions
Functional composition
Partial application
Memoization
A way of defining nameless functions
funx>x*2
Can be passed as parameter
Can be bound, i.e.
letsquare=funx>x*x
Used to provide LINQ-like features to lists and sequences
let myList = [1; 2; 3]
List.iter(funf>printfn%df)myList
Iterates through the collection
List.map(funf>f+1)myList
Returns a modified list [2; 3; 4] LINQ Select()
List.filter(funf>f%2=0)myList
Returns only odd elements LINQ Where()
Other useful functions (e.g., List.to_array)
Similar features in seq
Operators can be piped
values|>List.map(funf>f+1)
|>List.filter(funf>f>0)

And functionally composed


leteven=List.filter
(funf>f%2=0)
letpositive=List.filter
(funf>f>0)
letevenAndPos=even>>positive
evenAndPos[1;2;4]
yields [4]
letsquareThisx=
x*x
letaddFivex=
x+5
5|>squareThis|>addFive
yields 30
letsquareAndAddFive=
squareThis>>addFive
squareThisAndAddFive5
yields 30
letshift(dx,dy)(px,py)=
(px+dx,py+dy)

shift(1,0)(100,100)
result is (101, 100)

letshiftRight=shift(1,0)

shiftRight(100,100)
result is (101, 100)
Keep a lookaside table of computed values

letrecfibn=
ifn<=2then1
elsefib(n1)+fib(n2)

Computed values wasted


Why not cache them?
letfibFastn=
lett=newDictionary<int,int>()
letrecfibCachedn=
ift.ContainsKey(n)thent.[n]
elseifn<=2then1
elseletres=
fibCached(n1)+fibCached(n2)
t.Add(n,res)
res
fibCachedn
Computation expressions = workflows
builder { expression }
Usage
General programming (e.g., seq { })
Asynchronous workflows
Database queries
Define a builder type
Computation expression constructs map onto
the builder methods (are de-sugared)
E.g., leta=binc maps onto
builder.Let(b,(funa>c))
Builder aects behavior of contained
expressions
E.g., makes them asynchronous
Many .NET APIs feature Begin/End pairs
E.g., BeginGetResponse/EndGetResponse
Frameworks make code look sequential
Abstracting away Begin/End calls
C# AsyncEnumerator from PowerThreading
F# Async workflows
Goals
Begin an asynchronous operation
Resume execution when its done
Let threads interleave
Async<'a>
Represents a result of 'a computed in the future
This class needs to know about begin/end
pairs
Extends existing types with XXXAsync() calls
typeWebRequestwith
memberx.GetResponseAsync()=
Async.BuildPrimitive(
x.BeginGetResponse,
x.EndGetResponse)
Once Async knows about Begin/End elements
we can use the async { } workflow
letdownloadurl=
async{
letrq=WebRequest.Create(url)
let!resp=rq.GetResponseAsync()
uses=resp.GetResponseStram()
user=newStreamReader(s)
r.ReadToEnd()
}
let! fires o BeginGetResponse() asynchronously
and waits on completion
leturls=[
http://spbalt.net;
http://sp.ineta.ru;
http://altdotnet.org]

Spawn one-by-one
forurlinurlsdo
Async.Spawn(download(url))

Send all at once


urls|>List.map(funf>download(f))
|>Async.Parallel|>Async.Run
Foundations of F#
Robert Pickering

Expert F#
Don Syme et al.

F# for Scientists
Jon Harrop

You might also like