functional programming
Yuriy Taras
Advertisement
200 000 000 Active users / month
2 000 000 open TCP connections / physical server
Server side: Erlang on FreeBSD
500 000 000 tweets / day
200 000 000 users
Ruby on Rails, Scala
Spark
Implemented on Scala, use functional idioms for API
spark/bagel/src/main$ wc -l **/*.scala ...
592 total
AXD301
99.5% = 1.83 days/year
99.95% = 4.38 hours/year
99.999% = 5.26 minutes/year
99.9999999% = 0.63113 seconds/20 years
Observed in AXD301 telecom switch,
software layer implemented with Erlang
Due to Haskell’s strongly typed design, once we compiled our code, it just worked.Netrium, Energy Contracts Management System
Haskell enabled us to get into market in less than half the time!Silk, Web structured content management application
Haskell does exactly what we need it to do every time.JUMP, Online user management SaaS
OCaml’s type system <...> helps improve the quality of our code, catching bugs at the earliest possible stage. Billions of dollars of transactions flow through our systems every day, so getting it right matters.
JaneStreet, trading firm
Developed by Microsoft Research
Integrated into Visual Studio 2010
Heavy influence from OCaml and Haskell
LINQ, type inference, higher order functions and lambdas
higher order functions, lambdas, type inference
FP becomes mainstream
iMPERATIVE PARADIGM
.top
; add num1 to num2
mov di,num1+digits-1
mov si,num2+digits-1
mov cx,digits ;
call AddNumbers ; num2 += num1
mov bp,num2 ;
call PrintLine ;
dec dword [term] ; decrement loop counter
jz .done ;
; add num2 to num1
mov di,num2+digits-1
mov si,num1+digits-1
mov cx,digits ;
call AddNumbers ; num1 += num2
FUNCTIONAL PARADIGM
tan x = sin x / cos x
less is more
pure function
Function can't rely on any state but it's parameters
f(1) === f(1)
int f(int x) {
return x * 2;
}
"forbidden" functions
rand()
print()
writeFile()
readLn()
referential TRANSPARENCY
fac(3) === 6
- at compile time
- calculated in other thread
- calculated on other machine
- cached from previous call
other forbidden things
def a(b: Int): Int = {
b = b + 5
b
}
loops?
int factorial(int i) { int res = 1; for(j = i; j >= 2; j++) {
res *= j;
}
return res; }
recursion
def fac(i: Int): Int = if (i <= 1) 1 else fac(i - 1) * i
fail
scala> fac(50000)
java.lang.StackOverflowError
at .fac(:7)
NOT TURING COMPLETE :(
tail call optimization
def tailFac(i: Int, accumulator: Int) =
if (i <= 1)
accumulator
else tailFac(i -1, accumulator * i)
def factorial(i: Int) = tailFac(i, 1)
functions as first-class citizens
> let x = 0.0
> let y = sin
> y x
0.0
higher order functions
> def twice(fun: Double => Double, x: Double) = fun(fun(x))
> twice(Math.sin, 0)
res4: Double = 0.0
> twice(Math.cos, 0)
res6: Double = 0.5403023058681398
Lambda
> twice(_ * 2, 3)
res7: Double = 12.0
> def multiplier(x: Int): Int => Int = { x * _ }
> val mul2 = multiplier(2)
> mul2(4)
res9: Int = 8
> multiplier(4)(5)
res11: Int = 20
Cons and nil
collection functional api
> List(1, 2, 3) map { _ * 2 }
res13: List[Int] = List(2, 4, 6)
> List(1, 2, 3) filter { _ % 2 != 0 }
res15: List[Int] = List(1, 3)
> List(1, 2, 3) flatMap { x => List(x, x+1) }
res16: List[Int] = List(1, 2, 2, 3, 3, 4)
> List(1, 2, 3) reduceLeft { _ + _ }
res18: Int = 6
> List(1, 2, 3) reduceLeft { _ * _ }
res19: Int = 6
> List(1, 2, 3).foldLeft("") {(x: String, y: Int) => x + y.toString }
res29: java.lang.String = 123
one api to rule them all
- List
- Array
- Set
- Stack
- String
- Map
- Lazy stream
- Future (Akka)
- Distributed dataset (Spark)
- Option
billion dollar MISTAKE
I call it my billion-dollar mistake. It was the invention of the null reference in 1965.
String getUserName(Id id) {
User user = UserService.getUser(id);
if (user == null) return null;
Profile profile = user.getProfile();
if (profile != null) return null;
return profile.name;
}
def UserService.getUser(id: Id): User // Is there user or not?
Can you spot a bug?
def UserService.getUser(id: Id): Option[User]
UserService.getUser(id).profile // compile error
def getUserName(id: Id) = UserService.getUser(id) flatMap {
_.profile } map { _.name }
(sorry (but (I have) (no (time to show 'Lisp 'features))))
data Missing = Algebraic | Data Types
Notable languages
Scala
Java interop, C-like syntax, hybrid OO/FP, lot of experimental features
Haskell
Lazy, pure, type-safe, static typing, lightweight syntax
OCaml
mostly pure, type-safe, unfamiliar syntax, static typing, optional mutability and OO
F#
.Net interop, mostly pure, type-safe,
other things like OCaml
other things like OCaml
Scheme
mostly pure, dynamic, no syntax, consistent design
Clojure
mostly pure, dynamic with optional static typing, Java interop, compiles to bytecode, STM, optional OO
ERLANG
pure functions, lightweight threads aka actors, dynamic, optional type checking, MPS - concurrent and distributed, hot code reload
functional programming
By Yura Taras
functional programming
- 637