Functional programming
by Andraž Bajt
available at
Who am i?
CS student at FRI
developer at Koofr
STaaS provider startup
Entropy
Halting problem
Fighting entropy
Object Orientation
- model real world
- objects all the way down
- 3 rules
- design patterns
FUnCTIONS
Lambda Calculus
- Alonso Curch 1930s
- Equivalent to Turing Machine
LambDa CalCULUS
Very simple
Abstraction
λx.y
Application
f x
Composability!
WHAT IS FP?
WHAT IS FP?
Programming with values
Using function to transform values
MY STORY
(roughly)
- C(++)
- C#
- Java
- Python
- Scala
- Haskell
WHY MOVE TO FP LANd?
-
Composability
- Abstractions
GOT MATH?
Examples
function apply(f, x) {
return f(x);
}
apply(function(x){ return x * 2}, 1);
apply = (f,x) => f x
apply((x) => x * 2, 1)
CURRYING
apply = (f) => (x) => f x
apply((x) => x * 2)(1)
COMPOSITION
compose = (f) => (g) => (x) => f(g(x))
foo = (x) => x + 1
bar = (x) => x * 2
f = compose(foo)(bar)
f(2) # 5
Collections
people = [
{name: "John", surname: "Doe", age: 35},
{name: "Jane", surname: "Doe", age: 49}
]
people
.filter((p) => p.age > 40)
.map((p) => p.name + p.surname)
people.reduce(((total, p) => total + p.age), 0) / people.length
HELLO HASKELL WEB
main :: IO ()
main = scotty 3000 helloRoutes
helloRoutes :: ScottyM ()
helloRoutes = do
get "/" $ html "hello there"
get "/hello" $ html "Hello world"
post "/hello" $ html "Hello postman"
get "/hello/:name" $ do
name <- param "name"
html $ "Hello " `mappend` name
DSL
postUsersR :: Handler Value
postUsersR = do
Auth.adminOnly
user <- requireJsonBody
userIdMby <- runDB $ insertUnique user
runValidationHandler $
("username", "User with the supplied username already exists")
`validate` (isJust userIdMby)
getUsersUserR $ fromJust userIdMby
BUILDING A DSL
data Command a = Up a | Down a deriving (Eq, Show, Functor)
type Sequence = Free Command ()
up, down :: Sequence -> Sequence
up = Free . Up
down = Free . Down
done :: Sequence
done = Pure ()
go = ($done)
example = do
go up
go up
go down
go up
ORIGAMI
fsum :: (Num a) => Fold a a
fsum = Fold (+) 0 id
flen :: (Num b) => Fold a b
flen = Fold (\s _ -> s + 1) 0 fromInteger
favg :: (Fractional a) => Fold a a
favg = (/) <$> fsum <*> flen
example = runfold favg [1,2,3]
ORigami implementation
For foldable things
data Fold a b = forall x . Fold (x -> a -> x) x (x -> b)
instance Functor (Fold a) where
f `fmap` Fold step zero map = Fold step zero (f . map)
instance Applicative (Fold a) where
pure a = Fold const () (const a)
Fold f1 z1 m1 <*> Fold f2 z2 m2 = Fold f z m where
f (x1,x2) e = (f1 x1 e, f2 x2 e)
z = (z1, z2)
m (f, x) = (m1 f) (m2 x)
runfold :: (Foldable t) => Fold a b -> t a -> b
runfold (Fold f z m) t = m $ foldl' f z t
You should try it
Libraries for your language
Learn a new language!
Questions
Functional programming
By Andraž Bajt
Functional programming
- 967