F# in real world (LambdaCon15)

Yan Cui
Yan CuiSpeaker at Self
Yan Cui (@theburningmonk)
BOLOGNA 28 march 2015 LambdaCon
F# in the Real World
agenda
Hi, my name is Yan Cui.
F# in real world (LambdaCon15)
1MILLION USERS
ACTIVE
DAILY
250MILLION DAY
PER
REQUEST
2MONTH
TB
P E R
sec
ops
25,000
why F#?
time to market
correctness
efficient
tame complexity
17th April!
London
F# in real world (LambdaCon15)
Collectables
Wager Size
Special Symbol
Avg Wager Size
Web Server call
• Line Win!
– X number of matching symbols on adjacent columns!
– Positions have to be a ‘line’!
– Wild symbols substitute for other symbols!
!
• Scatter Win!
– X number of matching symbols anywhere!
– Triggers bonus game
What symbols should land?!
Any special symbol wins?!
Did the player win anything?
What the player’s new
average wager?
Should the player receive
collectables?
type Symbol = Standard! of string!
! ! ! | Wild
type Symbol = Standard! of string!
! ! ! | Wild
e.g.! Standard “hat”!
! Standard “shoe”!
! Standard “bonus”!
! …
type Symbol = Standard! of string!
! ! ! | Wild
i.e.! Wild
!
!
!
type Win = LineWin of int * Symbol * int!
! | ScatterWin of Symbol * int
!
!
!
type Win = LineWin of int * Symbol * int!
! | ScatterWin of Symbol * int
e.g.! LineWin (5, Standard “shoe”, 4)
!
!
!
type Win = LineWin of int * Symbol * int!
! | ScatterWin of Symbol * int
e.g.! ScatterWin (Standard “bonus”, 3)
type LineNum = int!
type Count! = int!
!
type Win = LineWin of LineNum * Symbol * Count!
! | ScatterWin of Symbol * Count
type LineNum = int!
type Count! = int!
!
type Win = LineWin of LineNum * Symbol * Count!
! | ScatterWin of Symbol * Count
e.g.! LineWin (5, Standard “shoe”, 4)
type LineNum = int!
type Count! = int!
!
type Win = LineWin of LineNum * Symbol * Count!
! | ScatterWin of Symbol * Count
e.g.! ScatterWin (Standard “bonus”, 3)
make invalid states
unrepresentable
NASA orbiter crashed
because one engineer
accidentally used miles
instead of kilometres
you’re never too smart
to make mistakes
[<Measure>]!
type Pence
e.g.! 42<Pence>!
! 153<Pence>!
! …
10<Meter> / 2<Second> ! = 5<Meter/Second>!
10<Meter> * 2<Second> ! = 20<Meter Second> !
10<Meter> + 10<Meter> ! = 20<Meter>!
10<Meter> * 10! ! ! = 100<Meter>!
10<Meter> * 10<Meter> ! = 100<Meter2>!
10<Meter> + 2<Second> ! // error!
10<Meter> + 2 ! ! ! // error
10<Meter> / 2<Second> ! = 5<Meter/Second>!
10<Meter> * 2<Second> ! = 20<Meter Second> !
10<Meter> + 10<Meter> ! = 20<Meter>!
10<Meter> * 10! ! ! = 100<Meter>!
10<Meter> * 10<Meter> ! = 100<Meter2>!
10<Meter> + 2<Second> ! // error!
10<Meter> + 2 ! ! ! // error
type Wager = int64<Pence>!
type Multiplier = int!
!
type Payout = Coins! of Wager!
! ! | MultipliedCoins of Multiplier * Wager!
! ! | Multi! of Payout list!
! ! | BonusGame
type Wager = int64<Pence>!
type Multiplier = int!
!
type Payout = Coins! of Wager!
! ! | MultipliedCoins of Multiplier * Wager!
! ! | Multi! of Payout list!
! ! | BonusGame
type Wager = int64<Pence>!
type Multiplier = int!
!
type Payout = Coins! of Wager!
! ! | MultipliedCoins of Multiplier * Wager!
! ! | Multi! of Payout list!
! ! | BonusGame
type State = !
{!
AvgWager! : Wager!
SpecialSymbol : Symbol!
Collectables : Map<Collectable, Count>!
}
F# in real world (LambdaCon15)
New avg wager Got a Collectable!
A pay line win!
F# in real world (LambdaCon15)
Betting small reduces avg wager!
Bonus Game!
F# in real world (LambdaCon15)
F# in real world (LambdaCon15)
type MonopolyBoardSpace = !
| RailRoad! ! of bool!
| Property! ! of int!
| ElectricCompany! of bool!
| WaterCompany! of bool!
| Chance! | CommunityChest!
| GotoJail! | Jail!
| FreeParking! | Go
type MonopolyBoardSpace = !
| RailRoad! ! of bool!
| Property! ! of int!
| ElectricCompany! of bool!
| WaterCompany! of bool!
| Chance! | CommunityChest!
| GotoJail! | Jail!
| FreeParking! | Go
type MonopolyBoardSpace = !
| RailRoad! ! of bool!
| Property! ! of int!
| ElectricCompany! of bool!
| WaterCompany! of bool!
| Chance! | CommunityChest!
| GotoJail! | Jail!
| FreeParking! | Go
type MonopolyBoardSpace = !
| RailRoad! ! of bool!
| Property! ! of int!
| ElectricCompany! of bool!
| WaterCompany! of bool!
| Chance! | CommunityChest!
| GotoJail! | Jail!
| FreeParking! | Go
[<Measure>]!
type Position!
!
type MonopolyBoard =!
{!
Spaces : MonopolyBoardSpace [ ]!
}!
member this.Item with !
get (pos : int<Position>) =!
this.Spaces.[int pos]
[<Measure>]!
type Position!
!
type MonopolyBoard =!
{!
Spaces : MonopolyBoardSpace [ ]!
}!
member this.Item with !
get (pos : int<Position>) = !
this.Spaces.[int pos]
F# in real world (LambdaCon15)
And a pay line win!
Coin size brought over
from main game
Houses = multiplier on wins
GAME OVER
Collected in the bonus game.
Gives player extra ‘lives’.
type BonusGameState =!
{!
Board ! : MonopolyBoard!
Position ! : int<Position>!
Lives ! : int<Life>!
Doubles! : int<Double>!
CoinSize! : Wager!
TotalWin! : Wager!
}
Coin size brought over
from main game
type BonusGameState =!
{!
Board ! : MonopolyBoard!
Position ! : int<Position>!
Lives ! : int<Life>!
Doubles! : int<Double>!
CoinSize! : Wager!
TotalWin! : Wager!
}
And a pay line win!
Houses = multiplier on wins
type BonusGameState =!
{!
Board ! : MonopolyBoard!
Position ! : int<Position>!
Lives ! : int<Life>!
Doubles! : int<Double>!
CoinSize! : Wager!
TotalWin! : Wager!
}
F# in real world (LambdaCon15)
F# in real world (LambdaCon15)
Collected in the bonus game.
Gives player extra ‘lives’.
type BonusGameState =!
{!
Board ! : MonopolyBoard!
Position ! : int<Position>!
Lives ! : int<Life>!
Doubles! : int<Double>!
CoinSize! : Wager!
TotalWin! : Wager!
}
0<Position>
let jail = 6<Position>
let rec move newPos state =!
match state.Board.[newPos] with!
…!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
…
let rec move newPos state =!
match state.Board.[newPos] with!
…!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
…
let rec move newPos state =!
match state.Board.[newPos] with!
…!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
…
let rec move newPos state =!
match state.Board.[newPos] with!
…!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
…
let rec move newPos state =!
match state.Board.[newPos] with!
…!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
…
let rec move newPos state =!
match state.Board.[newPos] with!
…!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
…
let rec move newPos state =!
match state.Board.[newPos] with!
…!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
…
let rec move newPos state =!
match state.Board.[newPos] with!
…!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
…
let rec move newPos state =!
match state.Board.[newPos] with!
…!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
…
let rec move newPos state =!
match state.Board.[newPos] with!
…!
| RailRoad true ! -> awardRailRoadMultiplier state!
| Property n when n > 0 -> awardPropertyMultiplier n state!
| ElectricityCompany true!
| WaterCompany true -> awardUtilityMultiplier state!
…
let rec move newPos state =!
match state.Board.[newPos] with!
…!
| CommunityChest! -> playCommunityChestCard state!
| Chance ! ! -> playChanceCard state!
…
let rec move newPos state =!
match state.Board.[newPos] with!
| RailRoad true ! -> awardRailRoadMultiplier state!
| Property n when n > 0 -> awardPropertyMultiplier n state!
| ElectricityCompany true!
| WaterCompany true -> awardUtilityMultiplier state!
| CommunityChest! -> playCommunityChestCard state!
| Chance ! ! -> playChanceCard state!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
| _ ! ! ! -> state
let rec move newPos state =!
match state.Board.[newPos] with!
| RailRoad true ! -> awardRailRoadMultiplier state!
| Property n when n > 0 -> awardPropertyMultiplier n state!
| ElectricityCompany true!
| WaterCompany true -> awardUtilityMultiplier state!
| CommunityChest! -> playCommunityChestCard state!
| Chance ! ! -> playChanceCard state!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
| _ ! ! ! -> state
let rec move newPos state =!
match state.Board.[newPos] with!
| RailRoad true ! -> awardRailRoadMultiplier state!
| Property n when n > 0 -> awardPropertyMultiplier n state!
| ElectricityCompany true!
| WaterCompany true -> awardUtilityMultiplier state!
| CommunityChest! -> playCommunityChestCard state!
| Chance ! ! -> playChanceCard state!
| GotoJail when state.Lives = 0<Life> -> !
! move jail state |> gameOver!
| GotoJail ! ! -> move jail state!
| _ ! ! ! -> state
F# in real world (LambdaCon15)
Recap
lightweight syntax to
create types and
hierarchies
great for domain
modelling
make invalid states
unrepresentable
clear, concise way to
handle branching
better correctness
order of magnitude
increase in productivity
F# in real world (LambdaCon15)
F# in real world (LambdaCon15)
player states are big
Stateless Server DatabaseClient
1:1 read-write ratio
stateless = !
Inefficient & Expensive
ServerClient
Session 1
Session 2
ServerClient Database
Elastic Load Balancer
S3
Auto scaling Group
Server A Server B
...
EC2
CloudFront
Stateful Server
The Actor Model
An actor is the fundamental unit of computation
which embodies the 3 things!
• Processing!
• Storage!
• Communication!
that are essential to computation.!
!
-Carl Hewitt*
* http://bit.ly/HoNHbG
The Actor Model
• Everything is an actor!
• An actor has a mailbox!
• When an actor receives a message it can:!
– Create new actors!
– Send messages to actors!
– Designate how to handle the next message
Stateful Server
• Gatekeeper!
– Manages the local list of active workers!
– Spawns new workers!
!
• Worker!
– Manages the states for a player!
– Optimistic locking!
– Persist state after period of inactivity
Stateful Server
Game Server
Player A
Player B
S3
Worker C
Worker B
Gatekeeper
RequestHandlers
Asynchronous
Stateful Server
Game Server
Worker C
Worker B
Gatekeeper
Worker A
ok
RequestHandlers
Player A
Player B
Asynchronous
S3
Stateful Server
Game Server
S3
Worker C
Worker B
Gatekeeper
Worker A
RequestHandlers
Player A
Player B
Asynchronous
Stateful Server
Game Server
S3
Worker C
Gatekeeper
Worker A
RequestHandlers
Player A
Player B
Asynchronous
Stateful Server
Game Server
Worker C
Worker A
Gatekeeper
error
RequestHandlers
Player A
Player B
S3
Asynchronous
type Agent<‘T> = MailboxProcessor<‘T>!
!
!
!
type Agent<‘T> = MailboxProcessor<‘T>!
!
type Message = !
| Get of AsyncReplyChannel<…>!
| Put of State * Version * AsyncReplyChannel<…>
type Agent<‘T> = MailboxProcessor<‘T>!
!
type Message = !
| Get of AsyncReplyChannel<…>!
| Put of State * Version * AsyncReplyChannel<…>
type Result<‘T> =!
| Success! of ’T!
| Failure! of Exception!
!
!
!
type Result<‘T> =!
| Success! of ’T!
| Failure! of Exception!
!
type GetResult = Result<State * Version>!
type PutResult = Result<unit>!
type Agent<‘T> = MailboxProcessor<‘T>!
!
type Message = !
| Get of AsyncReplyChannel<GetResult>!
| Put of State * Version * AsyncReplyChannel<PutResult>
type Agent<‘T> = MailboxProcessor<‘T>!
!
type Message = !
| Get of AsyncReplyChannel<GetResult>!
| Put of State * Version * AsyncReplyChannel<PutResult>
type Worker (playerId) =!
let agent = Agent<Message>.Start(fun inbox ->!
let state = getCurrentState playerId!
!
let rec workingState (state, version) = !
async { … }!
and closedState () =!
async { … }!
!
workingState (state, 1))
type Worker (playerId) =!
let agent = Agent<Message>.Start(fun inbox ->!
let state = getCurrentState playerId!
!
let rec workingState (state, version) = !
async { … }!
and closedState () =!
async { … }!
!
workingState (state, 1))
type Worker (playerId) =!
let agent = Agent<Message>.Start(fun inbox ->!
let state = getCurrentState playerId!
!
let rec workingState (state, version) = !
async { … }!
and closedState () =!
async { … }!
!
workingState (state, 1))
type Worker (playerId) =!
let agent = Agent<Message>.Start(fun inbox ->!
let state = getCurrentState playerId!
!
let rec workingState (state, version) = !
async { … }!
and closedState () =!
async { … }!
!
workingState (state, 1))
type Worker (playerId) =!
let agent = Agent<Message>.Start(fun inbox ->!
let state = getCurrentState playerId!
!
let rec workingState (state, version) = !
async { … }!
and closedState () =!
async { … }!
!
workingState (state, 1))
let rec workingState (state, version) = !
async { !
let! msg = inbox.TryReceive(60000)!
match msg with!
| None -> !
do! persist state!
return! closedState()!
…!
}!
let rec workingState (state, version) = !
async { !
let! msg = inbox.TryReceive(60000)!
match msg with!
| None -> !
do! persist state!
return! closedState()!
…!
}!
let rec workingState (state, version) = !
async { !
let! msg = inbox.TryReceive(60000)!
match msg with!
| None -> !
do! persist state!
return! closedState()!
…!
}!
non-blocking I/O
let rec workingState (state, version) = !
async { !
let! msg = inbox.TryReceive(60000)!
match msg with!
| None -> !
do! persist state!
return! closedState()!
…!
}!
let rec workingState (state, version) = !
async { !
let! msg = inbox.TryReceive(60000)!
match msg with!
| None -> !
do! persist state!
return! closedState()!
…!
}!
let rec workingState (state, version) = !
async { !
let! msg = inbox.TryReceive(60000)!
match msg with!
…!
| Some(Get(reply)) ->!
reply.Reply <| Success(state, version)!
return! workingState(state, version)!
…!
}!
let rec workingState (state, version) = !
async { !
let! msg = inbox.TryReceive(60000)!
match msg with!
…!
| Some(Put(newState, v, reply)) when version = v ->!
reply.Reply <| Success()!
return! workingState(newState, version+1)!
…!
}
let rec workingState (state, version) = !
async { !
let! msg = inbox.TryReceive(60000)!
match msg with!
…!
| Some(Put(_, v, reply)) ->!
reply.Reply <| Failure(VersionMismatch(version, v))!
return! workingState(state, version)!
}
let rec workingState (state, version) = !
async { !
let! msg = inbox.TryReceive(60000)!
match msg with!
| None ! ! ! ! ! ! -> …!
| Some(Get(reply)) ! ! ! ! -> …!
| Some(Put(newState, v, reply)) when version = v -> …!
| Some(Put(_, v, reply)) ! ! ! -> …!
}
and closedState () = !
async { !
let! msg = inbox.Receive()!
match msg with!
| Get(reply) ->!
reply.Reply <| Failure(WorkerStopped)!
return! closedState()!
| Put(_, _, reply) ->!
reply.Reply <| Failure(WorkerStopped)!
return! closedState()!
}
and closedState () = !
async { !
let! msg = inbox.Receive()!
match msg with!
| Get(reply) ->!
reply.Reply <| Failure(WorkerStopped)!
return! closedState()!
| Put(_, _, reply) ->!
reply.Reply <| Failure(WorkerStopped)!
return! closedState()!
}
F# in real world (LambdaCon15)
5x efficient
improvement
60% latency drop
no databases
90+% cost saving
need to ensure
server affinity
need to balance load
need to avoid
hotspots
• Persist player state after short inactivity!
• Move player to another server after persistence
need to gracefully
scale down
Recap
Agents!
• no locks!
• async message passing!
!
Agents!
• no locks!
• async message passing!
• self-contained!
• easy to reason with
Agents!
• low level!
• exceptions kills agents!
• primitive error monitoring!
• no supervision!
• no distribution
MS Orleans
Cricket
akka.Net
F# in real world (LambdaCon15)
Async Workflow!
• non-blocking I/O!
• no callbacks
Pattern Matching!
• clear & concise
F# in real world (LambdaCon15)
F# in real world (LambdaCon15)
Caught a Gnome
EXP Item Gold
Quest Progress
Caught a Gnome
Level Up
Quest Progress
EXP Item Gold
Caught a Gnome
Quest Complete
Level Up
Quest Progress
EXP Item Gold
Caught a Gnome
New Quest
Quest Complete
Quest Progress
EXP Item Gold
Caught a Gnome
Quest Complete
New Quest
Level Up
Quest Progress
New Quest
Achievement
Progress
EXP Item Gold
Quest Complete
Level Up
Caught a Gnome
Level Up
Quest Progress
EXP Item Gold
Caught a Gnome
Quest Complete
New Quest
Achievement
Progress
Achievement
Complete
Level Up
Quest Progress
EXP Item Gold
Caught a Gnome
Quest Complete
New Quest
Achievement
Progress
Achievement
Complete
100+ actions
triggered by different
abstraction layers
non-functional
requirements
message-broker
pattern
Caught Gnome Trapping
Queue
Levelling
Quests
Achievements
Analytics
Partner
Reporting
Caught Gnome Trapping
Queue
Levelling
Quests
Achievements
Analytics
Partner
Reporting
Ignore
Process
Process
Process
Process
Ignore
Caught Gnome Trapping
Queue
Levelling
Quests
Achievements
Analytics
Partner
Reporting
EXP
Item
Gold
Caught Gnome Trapping
Queue
Levelling
Quests
Achievements
Analytics
Partner
Reporting
EXP
Item
Gold
Caught Gnome Trapping
Queue
Levelling
Quests
Achievements
Analytics
Partner
Reporting
EXP
Item
Gold
Process
Ignore
Ignore
Ignore
Process
Ignore
Caught Gnome Trapping
Queue
Levelling
Quests
Achievements
Analytics
Partner
Reporting
EXP
Item
Gold
Level Up
Caught Gnome Trapping
Queue
Levelling
Quests
Achievements
Analytics
Partner
Reporting
EXP
Item
Gold
Level Up
need lots of facts
type Fact =!
| GotExp! ! of Exp!
| GotGold! ! of Gold!
| GotItem! ! of Item * Count!
| CaughtMonster! of Monster * Bait * Location!
| LevelUp! ! of OldLevel * NewLevel!
…
type Reward =!
| GotExp! ! of Exp!
| GotGold! ! of Gold!
| GotItem! ! of Item * Count!
!
type StateChange =!
| LevelUp! ! of OldLevel * NewLevel!
…
type Fact =!
| StateChange! of StateChange!
| Reward! ! of Reward!
| Trapping! ! of Trapping!
| Fishing! ! of Fishing!
…
let process fact =!
match fact with!
| StateChange(stateChange)! -> …!
| Reward(reward)! ! ! -> …!
| Trapping(trapping)! ! -> …!
…
C# interop
…!
var fact = Fact.NewStateChange(!
! StateChange.NewLevelUp(oldLvl, newLvl));!
…
type IFact = interface end!
!
type Reward =!
| GotExp! ! of Exp!
| GotGold! ! of Gold!
| GotItem! ! of Item * Count!
interface IFact
type IFact = interface end!
!
type Reward =!
| GotExp! ! of Exp!
| GotGold! ! of Gold!
| GotItem! ! of Item * Count!
interface IFact
let process (fact : IFact) =!
match fact with!
| :? StateChange ! as stateChange!-> …!
| :? Reward ! ! as reward! ! -> …!
| :? Trapping! ! as trapping! -> …!
…!
| _ -> raise <| NotSupportedFact fact
let process (fact : IFact) =!
match fact with!
| :? StateChange ! as stateChange!-> …!
| :? Reward ! ! as reward! ! -> …!
| :? Trapping! ! as trapping! -> …!
…!
| _ -> raise <| NotSupportedFact fact
simple
flexible
saver
F# in real world (LambdaCon15)
@theburningmonk
github.com/theburningmonk
theburningmonk.com
F# in real world (LambdaCon15)
http://hire.jobvite.com/m?3OHq4hwL
F#
C#
AWS
Erlang
Docker
micro-services
elasticsearch
redis
Google AppEngine
Google
BigQuery
PostSharpNeo4j
Python DevOps
PagerDuty
NewRelic
BOLOGNA 28 march 2015 LambdaCon
Leave your feedback on Joind.in!
https://joind.in/13652
1 of 184

Recommended

F# in the real world (CodeMotion Dubai) by
F# in the real world (CodeMotion Dubai)F# in the real world (CodeMotion Dubai)
F# in the real world (CodeMotion Dubai)Yan Cui
2.9K views210 slides
F# in the Real World (DDD EA) by
F# in the Real World (DDD EA)F# in the Real World (DDD EA)
F# in the Real World (DDD EA)Yan Cui
6.1K views213 slides
F# at GameSys by
F# at GameSysF# at GameSys
F# at GameSysYan Cui
5.1K views254 slides
F# in social gaming (CodeMash 15) by
F# in social gaming (CodeMash 15)F# in social gaming (CodeMash 15)
F# in social gaming (CodeMash 15)Yan Cui
2.4K views180 slides
Tame cloud complexity with F#-powered DSLs by
Tame cloud complexity with F#-powered DSLsTame cloud complexity with F#-powered DSLs
Tame cloud complexity with F#-powered DSLsYan Cui
20.8K views204 slides
Modelling game economy with Neo4j by
Modelling game economy with Neo4jModelling game economy with Neo4j
Modelling game economy with Neo4jYan Cui
42.6K views142 slides

More Related Content

What's hot

Ruby - Uma Introdução by
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma IntroduçãoÍgor Bonadio
208 views64 slides
Taking Perl to Eleven with Higher-Order Functions by
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsDavid Golden
278 views96 slides
Ruby is Awesome by
Ruby is AwesomeRuby is Awesome
Ruby is AwesomeAstrails
2.4K views182 slides
Desarrollando aplicaciones web en minutos by
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar J. Suárez
756 views239 slides
Rubyconf Bangladesh 2017 - Lets start coding in Ruby by
Rubyconf Bangladesh 2017 - Lets start coding in RubyRubyconf Bangladesh 2017 - Lets start coding in Ruby
Rubyconf Bangladesh 2017 - Lets start coding in RubyRuby Bangladesh
147 views40 slides
Big Design Conference: CSS3 by
Big Design Conference: CSS3 Big Design Conference: CSS3
Big Design Conference: CSS3 Wynn Netherland
1.7K views141 slides

What's hot(6)

Taking Perl to Eleven with Higher-Order Functions by David Golden
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
David Golden278 views
Ruby is Awesome by Astrails
Ruby is AwesomeRuby is Awesome
Ruby is Awesome
Astrails2.4K views
Desarrollando aplicaciones web en minutos by Edgar J. Suárez
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
Edgar J. Suárez756 views
Rubyconf Bangladesh 2017 - Lets start coding in Ruby by Ruby Bangladesh
Rubyconf Bangladesh 2017 - Lets start coding in RubyRubyconf Bangladesh 2017 - Lets start coding in Ruby
Rubyconf Bangladesh 2017 - Lets start coding in Ruby
Ruby Bangladesh147 views
Big Design Conference: CSS3 by Wynn Netherland
Big Design Conference: CSS3 Big Design Conference: CSS3
Big Design Conference: CSS3
Wynn Netherland1.7K views

Similar to F# in real world (LambdaCon15)

ViewController/State by
ViewController/StateViewController/State
ViewController/Stategillygize
594 views27 slides
HadoopとMongoDBを活用したソーシャルアプリのログ解析 by
HadoopとMongoDBを活用したソーシャルアプリのログ解析HadoopとMongoDBを活用したソーシャルアプリのログ解析
HadoopとMongoDBを活用したソーシャルアプリのログ解析Takahiro Inoue
7.5K views57 slides
Tsi challenger-overview-copy[1] by
Tsi challenger-overview-copy[1]Tsi challenger-overview-copy[1]
Tsi challenger-overview-copy[1]jeff dorsey
310 views28 slides
F# in social gaming by Yan Cui at Codemotion Dubai by
F# in social gaming by Yan Cui at Codemotion DubaiF# in social gaming by Yan Cui at Codemotion Dubai
F# in social gaming by Yan Cui at Codemotion DubaiCodemotion Dubai
173 views210 slides
Short Term Risk From Long Term Models by
Short Term Risk From Long Term ModelsShort Term Risk From Long Term Models
Short Term Risk From Long Term ModelsDickGlidden
325 views27 slides
F# in the real world (NDC) by
F# in the real world (NDC)F# in the real world (NDC)
F# in the real world (NDC)Yan Cui
260.7K views222 slides

Similar to F# in real world (LambdaCon15)(7)

ViewController/State by gillygize
ViewController/StateViewController/State
ViewController/State
gillygize594 views
HadoopとMongoDBを活用したソーシャルアプリのログ解析 by Takahiro Inoue
HadoopとMongoDBを活用したソーシャルアプリのログ解析HadoopとMongoDBを活用したソーシャルアプリのログ解析
HadoopとMongoDBを活用したソーシャルアプリのログ解析
Takahiro Inoue7.5K views
Tsi challenger-overview-copy[1] by jeff dorsey
Tsi challenger-overview-copy[1]Tsi challenger-overview-copy[1]
Tsi challenger-overview-copy[1]
jeff dorsey310 views
F# in social gaming by Yan Cui at Codemotion Dubai by Codemotion Dubai
F# in social gaming by Yan Cui at Codemotion DubaiF# in social gaming by Yan Cui at Codemotion Dubai
F# in social gaming by Yan Cui at Codemotion Dubai
Codemotion Dubai173 views
Short Term Risk From Long Term Models by DickGlidden
Short Term Risk From Long Term ModelsShort Term Risk From Long Term Models
Short Term Risk From Long Term Models
DickGlidden325 views
F# in the real world (NDC) by Yan Cui
F# in the real world (NDC)F# in the real world (NDC)
F# in the real world (NDC)
Yan Cui260.7K views
Dot net in social gaming by Yan Cui
Dot net in social gamingDot net in social gaming
Dot net in social gaming
Yan Cui1.6K views

More from Yan Cui

How to win the game of trade-offs by
How to win the game of trade-offsHow to win the game of trade-offs
How to win the game of trade-offsYan Cui
21 views84 slides
How to choose the right messaging service by
How to choose the right messaging serviceHow to choose the right messaging service
How to choose the right messaging serviceYan Cui
135 views118 slides
How to choose the right messaging service for your workload by
How to choose the right messaging service for your workloadHow to choose the right messaging service for your workload
How to choose the right messaging service for your workloadYan Cui
65 views113 slides
Patterns and practices for building resilient serverless applications.pdf by
Patterns and practices for building resilient serverless applications.pdfPatterns and practices for building resilient serverless applications.pdf
Patterns and practices for building resilient serverless applications.pdfYan Cui
170 views137 slides
Lambda and DynamoDB best practices by
Lambda and DynamoDB best practicesLambda and DynamoDB best practices
Lambda and DynamoDB best practicesYan Cui
817 views148 slides
Lessons from running AppSync in prod by
Lessons from running AppSync in prodLessons from running AppSync in prod
Lessons from running AppSync in prodYan Cui
1.1K views102 slides

More from Yan Cui(20)

How to win the game of trade-offs by Yan Cui
How to win the game of trade-offsHow to win the game of trade-offs
How to win the game of trade-offs
Yan Cui21 views
How to choose the right messaging service by Yan Cui
How to choose the right messaging serviceHow to choose the right messaging service
How to choose the right messaging service
Yan Cui135 views
How to choose the right messaging service for your workload by Yan Cui
How to choose the right messaging service for your workloadHow to choose the right messaging service for your workload
How to choose the right messaging service for your workload
Yan Cui65 views
Patterns and practices for building resilient serverless applications.pdf by Yan Cui
Patterns and practices for building resilient serverless applications.pdfPatterns and practices for building resilient serverless applications.pdf
Patterns and practices for building resilient serverless applications.pdf
Yan Cui170 views
Lambda and DynamoDB best practices by Yan Cui
Lambda and DynamoDB best practicesLambda and DynamoDB best practices
Lambda and DynamoDB best practices
Yan Cui817 views
Lessons from running AppSync in prod by Yan Cui
Lessons from running AppSync in prodLessons from running AppSync in prod
Lessons from running AppSync in prod
Yan Cui1.1K views
Serverless observability - a hero's perspective by Yan Cui
Serverless observability - a hero's perspectiveServerless observability - a hero's perspective
Serverless observability - a hero's perspective
Yan Cui385 views
How to ship customer value faster with step functions by Yan Cui
How to ship customer value faster with step functionsHow to ship customer value faster with step functions
How to ship customer value faster with step functions
Yan Cui652 views
How serverless changes the cost paradigm by Yan Cui
How serverless changes the cost paradigmHow serverless changes the cost paradigm
How serverless changes the cost paradigm
Yan Cui1.1K views
Why your next serverless project should use AWS AppSync by Yan Cui
Why your next serverless project should use AWS AppSyncWhy your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSync
Yan Cui1.3K views
Build social network in 4 weeks by Yan Cui
Build social network in 4 weeksBuild social network in 4 weeks
Build social network in 4 weeks
Yan Cui642 views
Patterns and practices for building resilient serverless applications by Yan Cui
Patterns and practices for building resilient serverless applicationsPatterns and practices for building resilient serverless applications
Patterns and practices for building resilient serverless applications
Yan Cui393 views
How to bring chaos engineering to serverless by Yan Cui
How to bring chaos engineering to serverlessHow to bring chaos engineering to serverless
How to bring chaos engineering to serverless
Yan Cui456 views
Migrating existing monolith to serverless in 8 steps by Yan Cui
Migrating existing monolith to serverless in 8 stepsMigrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 steps
Yan Cui402 views
Building a social network in under 4 weeks with Serverless and GraphQL by Yan Cui
Building a social network in under 4 weeks with Serverless and GraphQLBuilding a social network in under 4 weeks with Serverless and GraphQL
Building a social network in under 4 weeks with Serverless and GraphQL
Yan Cui289 views
FinDev as a business advantage in the post covid19 economy by Yan Cui
FinDev as a business advantage in the post covid19 economyFinDev as a business advantage in the post covid19 economy
FinDev as a business advantage in the post covid19 economy
Yan Cui546 views
How to improve lambda cold starts by Yan Cui
How to improve lambda cold startsHow to improve lambda cold starts
How to improve lambda cold starts
Yan Cui867 views
What can you do with lambda in 2020 by Yan Cui
What can you do with lambda in 2020What can you do with lambda in 2020
What can you do with lambda in 2020
Yan Cui1K views
A chaos experiment a day, keeping the outage away by Yan Cui
A chaos experiment a day, keeping the outage awayA chaos experiment a day, keeping the outage away
A chaos experiment a day, keeping the outage away
Yan Cui385 views
How to debug slow lambda response times by Yan Cui
How to debug slow lambda response timesHow to debug slow lambda response times
How to debug slow lambda response times
Yan Cui317 views

Recently uploaded

"Node.js vs workers — A comparison of two JavaScript runtimes", James M Snell by
"Node.js vs workers — A comparison of two JavaScript runtimes", James M Snell"Node.js vs workers — A comparison of two JavaScript runtimes", James M Snell
"Node.js vs workers — A comparison of two JavaScript runtimes", James M SnellFwdays
14 views30 slides
Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And... by
Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And...Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And...
Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And...ShapeBlue
108 views12 slides
Business Analyst Series 2023 - Week 4 Session 7 by
Business Analyst Series 2023 -  Week 4 Session 7Business Analyst Series 2023 -  Week 4 Session 7
Business Analyst Series 2023 - Week 4 Session 7DianaGray10
146 views31 slides
The Power of Heat Decarbonisation Plans in the Built Environment by
The Power of Heat Decarbonisation Plans in the Built EnvironmentThe Power of Heat Decarbonisation Plans in the Built Environment
The Power of Heat Decarbonisation Plans in the Built EnvironmentIES VE
84 views20 slides
MVP and prioritization.pdf by
MVP and prioritization.pdfMVP and prioritization.pdf
MVP and prioritization.pdfrahuldharwal141
39 views8 slides
Innovation & Entrepreneurship strategies in Dairy Industry by
Innovation & Entrepreneurship strategies in Dairy IndustryInnovation & Entrepreneurship strategies in Dairy Industry
Innovation & Entrepreneurship strategies in Dairy IndustryPervaizDar1
35 views26 slides

Recently uploaded(20)

"Node.js vs workers — A comparison of two JavaScript runtimes", James M Snell by Fwdays
"Node.js vs workers — A comparison of two JavaScript runtimes", James M Snell"Node.js vs workers — A comparison of two JavaScript runtimes", James M Snell
"Node.js vs workers — A comparison of two JavaScript runtimes", James M Snell
Fwdays14 views
Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And... by ShapeBlue
Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And...Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And...
Enabling DPU Hardware Accelerators in XCP-ng Cloud Platform Environment - And...
ShapeBlue108 views
Business Analyst Series 2023 - Week 4 Session 7 by DianaGray10
Business Analyst Series 2023 -  Week 4 Session 7Business Analyst Series 2023 -  Week 4 Session 7
Business Analyst Series 2023 - Week 4 Session 7
DianaGray10146 views
The Power of Heat Decarbonisation Plans in the Built Environment by IES VE
The Power of Heat Decarbonisation Plans in the Built EnvironmentThe Power of Heat Decarbonisation Plans in the Built Environment
The Power of Heat Decarbonisation Plans in the Built Environment
IES VE84 views
Innovation & Entrepreneurship strategies in Dairy Industry by PervaizDar1
Innovation & Entrepreneurship strategies in Dairy IndustryInnovation & Entrepreneurship strategies in Dairy Industry
Innovation & Entrepreneurship strategies in Dairy Industry
PervaizDar135 views
Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or... by ShapeBlue
Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or...Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or...
Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or...
ShapeBlue199 views
Future of AR - Facebook Presentation by Rob McCarty
Future of AR - Facebook PresentationFuture of AR - Facebook Presentation
Future of AR - Facebook Presentation
Rob McCarty65 views
PCCC23:日本AMD株式会社 テーマ1「AMD Instinct™ アクセラレーターの概要」 by PC Cluster Consortium
PCCC23:日本AMD株式会社 テーマ1「AMD Instinct™ アクセラレーターの概要」PCCC23:日本AMD株式会社 テーマ1「AMD Instinct™ アクセラレーターの概要」
PCCC23:日本AMD株式会社 テーマ1「AMD Instinct™ アクセラレーターの概要」
"Package management in monorepos", Zoltan Kochan by Fwdays
"Package management in monorepos", Zoltan Kochan"Package management in monorepos", Zoltan Kochan
"Package management in monorepos", Zoltan Kochan
Fwdays34 views
Digital Personal Data Protection (DPDP) Practical Approach For CISOs by Priyanka Aash
Digital Personal Data Protection (DPDP) Practical Approach For CISOsDigital Personal Data Protection (DPDP) Practical Approach For CISOs
Digital Personal Data Protection (DPDP) Practical Approach For CISOs
Priyanka Aash162 views
Transcript: Redefining the book supply chain: A glimpse into the future - Tec... by BookNet Canada
Transcript: Redefining the book supply chain: A glimpse into the future - Tec...Transcript: Redefining the book supply chain: A glimpse into the future - Tec...
Transcript: Redefining the book supply chain: A glimpse into the future - Tec...
BookNet Canada41 views
Discover Aura Workshop (12.5.23).pdf by Neo4j
Discover Aura Workshop (12.5.23).pdfDiscover Aura Workshop (12.5.23).pdf
Discover Aura Workshop (12.5.23).pdf
Neo4j15 views
AI + Memoori = AIM by Memoori
AI + Memoori = AIMAI + Memoori = AIM
AI + Memoori = AIM
Memoori14 views
Initiating and Advancing Your Strategic GIS Governance Strategy by Safe Software
Initiating and Advancing Your Strategic GIS Governance StrategyInitiating and Advancing Your Strategic GIS Governance Strategy
Initiating and Advancing Your Strategic GIS Governance Strategy
Safe Software184 views
Cocktail of Environments. How to Mix Test and Development Environments and St... by Aleksandr Tarasov
Cocktail of Environments. How to Mix Test and Development Environments and St...Cocktail of Environments. How to Mix Test and Development Environments and St...
Cocktail of Environments. How to Mix Test and Development Environments and St...
This talk was not generated with ChatGPT: how AI is changing science by Elena Simperl
This talk was not generated with ChatGPT: how AI is changing scienceThis talk was not generated with ChatGPT: how AI is changing science
This talk was not generated with ChatGPT: how AI is changing science
Elena Simperl32 views
Mobile Core Solutions & Successful Cases.pdf by IPLOOK Networks
Mobile Core Solutions & Successful Cases.pdfMobile Core Solutions & Successful Cases.pdf
Mobile Core Solutions & Successful Cases.pdf
IPLOOK Networks14 views
Deep Tech and the Amplified Organisation: Core Concepts by Holonomics
Deep Tech and the Amplified Organisation: Core ConceptsDeep Tech and the Amplified Organisation: Core Concepts
Deep Tech and the Amplified Organisation: Core Concepts
Holonomics17 views

F# in real world (LambdaCon15)