tour of language landscape
Post on 24-Jul-2015
2.482 Views
Preview:
TRANSCRIPT
tour guide : Yan Cui @theburningmonk
Hi, my name is Yan Cui.
1MILLION USERS
ACTIVEDAILY
250MILLION DAY
PERREQUEST
2MONTH
TBP E R
secops25,000
agenda
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Borrowed Pointers Dependent Types
Uniqueness Types
Bit SyntaxSignals
Macros
Unit-of-Measure
Actor Model
disclaimers
syntax!doesn’t matter
Being literate isn't simply a matter of being able to put words on the page, it's solidifying our thoughts such that they can be written.
Interpreting and applying someone else's thoughts is the equivalent for reading. We call
these composition and comprehension. And they are what literacy really is.
- Chris Granger
Coding, like writing, is a mechanical act… Just like writing, we have to know how to solidify
our thoughts and get them out of our head…!We build mental models of everything… If we want computers to be able to compute for us, then we have to accurately extract these models from our heads and record them.
- Chris Granger
IDEAS matter
“Programming languages have a devious influence: they shape our thinking
habits.”
- Edsger W. Dijkstra
“One of the most disastrous thing we can learn is the first programming language, even
if it's a good programming language.”
- Alan Kay
“Just as there are odours that dogs can smell and we cannot, as well as sounds that dogs can hear
and we cannot, so too there are wavelengths of light we cannot see and flavours we cannot taste. Why
then, given our brains wired the way they are, does the remark "Perhaps there are thoughts we cannot think," surprise you? Evolution, so far, may possibly have blocked us from being able to think in some
directions; there could be unthinkable thoughts.”
- Richard Hamming
“Just as there are odours that dogs can smell and we cannot, as well as sounds that dogs can hear
and we cannot, so too there are wavelengths of light we cannot see and flavours we cannot taste. Why
then, given our brains wired the way they are, does the remark "Perhaps there are thoughts we cannot think," surprise you? Evolution, so far, may possibly have blocked us from being able to think in some
directions; there could be unthinkable thoughts.”
- Richard Hamming
“The limits of my language means the limits of my world.”
- Ludwig Wittgenstein
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Borrowed Pointers Dependent Types
Uniqueness Types
Bit SyntaxSignals
Macros
Unit-of-Measure
Actor Model
your app
your app
CSVCSVCSV
CSVCSVXML
your app
CSVCSVCSV
CSVCSVXML
some service
your app
CSVCSVCSV
CSVCSVXML
some service
DB
1. define DTO types!2. I/O!3. marshal data into DTO!4. do useful work
1. define DTO types!2. I/O!3. marshal data into DTO!4. do useful work
compilerprovideexternal
data source typed info
type providers
intellisense!tooltips!
…
compile time validation
no code generation
R
FunScript AzureAmazon S3
CSVSQLiteSQL Server
WSDL
WorldBank
RegexODATA IKVM
FacebookApiary
XAMLFreebaseHadoop
Oracle
Minesweeper
Don SymePowershell
JSON
Fizzbuzz
Mixin
RSS
MatlabDates
NorthPole
XML
Python
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Borrowed Pointers Dependent Types
Uniqueness Types
Bit SyntaxSignals
Macros
Unit-of-Measure
Actor Model
“…a clean design is one that supports visual thinking so
people can meet their informational needs with a
minimum of conscious effort.”
- Daniel Higginbotham (www.visualmess.com)
Whilst talking with an ex-colleague, a question came up on how to implement the Stable Marriage problem using a message passing approach. Naturally, I wanted to answer that question with Erlang!!!Let’s first dissect the problem and decide what processes we need and how they need to interact with one another.!!The stable marriage problem is commonly stated as:!Given n men and n women, where each person has ranked all members of the opposite sex with a unique number between 1 and n in order of preference, marry the men and women together such that there are no two people of opposite sex who would both rather have each other than their current partners. If there are no such people, all the marriages are “stable”. (It is assumed that the participants are binary gendered and that marriages are not same-sex).!From the problem description, we can see that we need:!* a module for man!* a module for woman!* a module for orchestrating the experiment!In terms of interaction between the different modules, I imagined something along the lines of…
how we read ENGLISH
see also http://bit.ly/1KN8cd0
Whilst talking with an ex-colleague, a question came up on how to implement the Stable Marriage problem using a message passing approach. Naturally, I wanted to answer that question with Erlang!!!Let’s first dissect the problem and decide what processes we need and how they need to interact with one another.!!The stable marriage problem is commonly stated as:!Given n men and n women, where each person has ranked all members of the opposite sex with a unique number between 1 and n in order of preference, marry the men and women together such that there are no two people of opposite sex who would both rather have each other than their current partners. If there are no such people, all the marriages are “stable”. (It is assumed that the participants are binary gendered and that marriages are not same-sex).!From the problem description, we can see that we need:!* a module for man!* a module for woman!* a module for orchestrating the experiment!In terms of interaction between the different modules, I imagined something along the lines of…
2. top-to-bottom1.left-to-right
how we read ENGLISH
see also http://bit.ly/1KN8cd0
how we read CODE
public void DoSomething(int x, int y)!{! Foo(y,! Bar(x,! Zoo(Monkey())));!}
see also http://bit.ly/1KN8cd0
how we read CODE
public void DoSomething(int x, int y)!{! Foo(y,! Bar(x,! Zoo(Monkey())));!}
2. bottom-to-top
1.right-to-left
see also http://bit.ly/1KN8cd0
Whilst talking with an ex-colleague, a question came up on how to implement the Stable Marriage problem using a message passing approach. Naturally, I wanted to answer that question with Erlang!!!Let’s first dissect the problem and decide what processes we need and how they need to interact with one another.!!The stable marriage problem is commonly stated as:!Given n men and n women, where each person has ranked all members of the opposite sex with a unique number between 1 and n in order of preference, marry the men and women together such that there are no two people of opposite sex who would both rather have each other than their current partners. If there are no such people, all the marriages are “stable”. (It is assumed that the participants are binary gendered and that marriages are not same-sex).!From the problem description, we can see that we need:!* a module for man!* a module for woman!* a module for orchestrating the experiment!In terms of interaction between the different modules, I imagined something along the lines of…
2. top-to-bottom
1.left-to-right
how we read ENGLISH
public void DoSomething(int x, int y)!{! Foo(y,! Bar(x,! Zoo(Monkey())));!}
2. top-to-bottom
1.right-to-left
how we read CODE
see also http://bit.ly/1KN8cd0
“…a clean design is one that supports visual thinking so
people can meet their informational needs with a
minimum of conscious effort.”
|>
how we read CODE
let drawCircle x y radius = radius |> circle |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)
see also http://bit.ly/1KN8cd0
how we read CODE
let drawCircle x y radius = radius |> circle |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)
2. top-to-bottom1.left-to-right
see also http://bit.ly/1KN8cd0
let drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)
see also http://bit.ly/1KN8cd0
let drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)
see also http://bit.ly/1KN8cd0
let drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)
see also http://bit.ly/1KN8cd0
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Borrowed Pointers Dependent Types
Uniqueness Types
Bit SyntaxSignals
Macros
Unit-of-Measure
Actor Model
NASA orbiter crashed because one engineer accidentally used miles instead of kilometres
you’re never too smart to make mistakes
unit-of-measure
[<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 Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Borrowed Pointers Dependent Types
Uniqueness Types
Bit SyntaxSignals
Macros
Unit-of-Measure
Actor Model
Duck Typing
If it looks like a duck and quacks like a duck, it's a duck
def say_quack(duck): duck.quack()
def say_quack(duck): duck.quack()
class Duck: def quack(self): print("quack quack!”)
class Duck: def quack(self): print("quack quack!”) !
duck = Duck() say_quack(duck) !
> quack quack!
class Bird: def quack(self): print(“tweet tweet!”)
class Bird: def quack(self): print(“tweet tweet!”) !
bird = Bird() say_quack(bird) !
> tweet tweet!
ConvenienceSafety
what if…
statically resolved!
type parameters
let inline sayQuack (duck : ^a) = (^a : (member Quack : unit -> unit) duck)
see also http://bit.ly/1H2fN9i
let inline sayQuack (duck : ^a) = (^a : (member Quack : unit -> unit) duck)
see also http://bit.ly/1H2fN9i
let inline sayQuack (duck : ^a) = (^a : (member Quack : unit -> unit) duck)
see also http://bit.ly/1H2fN9i
let inline sayQuack (duck : ^a) = (^a : (member Quack : unit -> unit) duck)
see also http://bit.ly/1H2fN9i
type Duck () = member __.Quack() = printfn “quack quack!” !
let duck = Duck() sayQuack duck !
> quack quack!see also http://bit.ly/1H2fN9i
type Bird () = member __.Quack() = printfn “tweet tweet!” !
let bird = Bird() sayQuack bird !
> tweet tweet!see also http://bit.ly/1H2fN9i
type Dog () = member __.Bark() = printfn “woof woof!” !
let dog = Dog() sayQuack dog !error FS0001: The type ‘Dog’ does not support the operator ‘Quack’
see also http://bit.ly/1H2fN9i
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Borrowed Pointers Dependent Types
Uniqueness Types
Bit SyntaxSignals
Macros
Unit-of-Measure
Actor Model
implicit interface!
implementation
type Donald struct { } func (d Donald) Quack() { fmt.Println(“quack quack!”) }
see also http://bit.ly/1ER5zVs
type Bird struct { } func (b Bird) Quack() { fmt.Println(“tweet tweet!”) }
see also http://bit.ly/1ER5zVs
func main() { donald := Donald{} sayQuack(donald) bird := Bird{} sayQuack(bird) }
see also http://bit.ly/1ER5zVs
quack quack!
func main() { donald := Donald{} sayQuack(donald) bird := Bird{} sayQuack(bird) }
tweet tweet!
func main() { donald := Donald{} sayQuack(donald) bird := Bird{} sayQuack(bird) }
type Dog struct { } func (d Dog) Bark() { fmt.Println(“woof woof!”) }
see also http://bit.ly/1ER5zVs
func main() { dog := Dog{} sayQuack(dog) }
main.go:40: cannot use dog (type Dog) as type Duck in argument to sayQuack:!! Dog does not implement Duck (missing Quack method)
see also http://bit.ly/1ER5zVs
system building is also a process of learning
and discovery
see also http://bit.ly/1ER5zVs
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Borrowed Pointers Dependent Types
Uniqueness Types
Bit SyntaxSignals
Macros
Unit-of-Measure
Actor Model
Homoiconicity
…homoiconicity is a property of some programming languages in which the program structure is similar to its syntax, and therefore the program’s internal representation can be
inferred by reading the text’s layout…
code is data data is code
quote
(+ 1 2) => 3 (quote (+ 1 2)) => (+ 1 2) ‘(+ 1 2) => (+ 1 2)see also http://bit.ly/1PpIrjS
macros
(defmacro assert-equals [actual expected] ‘(let [actual-val# ~actual] (when-not (= actual-val# ~expected) (throw (AssertionError. (str “FAIL in “ ‘~actual “\n expected: “ ‘~expected “\n actual: “ actual-val#))))))
see also http://bit.ly/1PpIrjS
(assert-equals (inc 1) 2) ; => nil (assert-equals (inc 1) (+ 0 1)) ; => AssertionError FAIL in (inc 1) ; expected: (+ 0 1) ; actual: 2
see also http://bit.ly/1PpIrjS
(assert-equals (inc 1) 2) ; => nil (assert-equals (inc 1) (+ 0 1)) ; => AssertionError FAIL in (inc 1) ; expected: (+ 0 1) ; actual: 2
see also http://bit.ly/1PpIrjS
(assert-equals (inc 1) 2) ; => nil (assert-equals (inc 1) (+ 0 1)) ; => AssertionError FAIL in (inc 1) ; expected: (+ 0 1) ; actual: 2
see also http://bit.ly/1PpIrjS
huh?? where? what? how?
(defmacro assert-equals [actual expected] ‘(let [actual-val# ~actual] (when-not (= actual-val# ~expected) (throw (AssertionError. (str “FAIL in “ ‘~actual “\n expected: “ ‘~expected “\n actual: “ actual-val#))))))
(assert-equals (inc 1) (+ 0 1))
see also http://bit.ly/1PpIrjS
(defmacro assert-equals [actual expected] ‘(let [actual-val# ~actual] (when-not (= actual-val# ~expected) (throw (AssertionError. (str “FAIL in “ ‘~actual “\n expected: “ ‘~expected “\n actual: “ actual-val#))))))
(assert-equals (inc 1) (+ 0 1))
see also http://bit.ly/1PpIrjS
(defmacro assert-equals [actual expected] ‘(let [actual-val# ~actual] (when-not (= actual-val# ~expected) (throw (AssertionError. (str “FAIL in “ ‘~actual “\n expected: “ ‘~expected “\n actual: “ actual-val#))))))
(assert-equals (inc 1) (+ 0 1))
see also http://bit.ly/1PpIrjS
see also http://bit.ly/1PpIrjS
(defmacro assert-equals [actual expected] ‘(let [actual-val# ~actual] (when-not (= actual-val# ~expected) (throw (AssertionError. (str “FAIL in “ ‘~actual “\n expected: “ ‘~expected “\n actual: “ actual-val#))))))
see also http://bit.ly/1PpIrjS
(macroexpand '(assert-equals (inc 1) (+ 0 1))) ; => ; (let* [actual-value__16087__auto__ (inc 1)] ; (clojure.core/when-not ; (clojure.core/= actual-value__16087__auto__ (+ 0 1)) ; (throw (java.lang.AssertionError. ; (clojure.core/str ; "FAIL in " (quote (inc 1)) ; "\nexpected: " (quote (+ 0 1)) ; "\n actual: " actual-value__16087__auto__)))))
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Borrowed Pointers Dependent Types
Uniqueness Types
Bit SyntaxSignals
Macros
Unit-of-Measure
Actor Model
GC is great
runtime cost
fn foo() { // v has ownership of the vector let v = vec![1, 2, 3]; // mutable binding let mut v2 = vec![]; } // vector is deallocated at the // end of scope, // this happens deterministically
see also http://bit.ly/1F6WBVD
// take ownership let v = vec![1, 2, 3]; !// moved ownership to v2 let v2 = v;
see also http://bit.ly/1F6WBVD
// take ownership let v = vec![1, 2, 3]; !// moved ownership to v2 let v2 = v; !println!("v[0] is {}", v[0]); // error: use of moved value: `v` // println!("v[0] is {}", v[0]); // ^
see also http://bit.ly/1F6WBVD
fn take(v : Vec<i32>) { // ownership of vector transferred // to v in this scope }
see also http://bit.ly/1F6WBVD
// take ownership let v = vec![1, 2, 3]; !// moved ownership take(v);
see also http://bit.ly/1F6WBVD
// take ownership let v = vec![1, 2, 3]; !// moved ownership take(v); !println!("v[0] is {}", v[0]); // error: use of moved value: `v` // println!("v[0] is {}", v[0]); // ^
see also http://bit.ly/1F6WBVD
// note we're taking a reference, // &Vec<i32>, instead of Vec<i32> fn take(v : &Vec<i32>) { // no need to deallocate the vector // after we go out of scope here }
see also http://bit.ly/1F6WBVD
// take ownership let v = vec![1, 2, 3]; !// notice we're passing a reference, // &v, instead of v take(&v); // borrow ownership !println!("v[0] is {}", v[0]); // v[0] is 1
see also http://bit.ly/1F6WBVD
fn take(v : &Vec<i32>) { v.push(5); } !let v = vec![]; take(&v); // cannot borrow immutable borrowed // content `*v` as mutable // v.push(5); // ^
see also http://bit.ly/1F6WBVD
fn take(v : &mut Vec<i32>) { v.push(5); } !let mut v = vec![]; take(&mut v); !println!("v[0] is {}", v[0]); // v[0] is 5
see also http://bit.ly/1F6WBVD
see also http://bit.ly/1F6WBVD
Rule 1.!!
the borrower’s scope must not outlast the owner
see also http://bit.ly/1F6WBVD
Rule 2.!!
one of the following, but not both:! 2.1 0 or more refs to a resource! 2.2 exactly 1 mutable ref
see also http://bit.ly/1F6WBVD
data race
There is a ‘data race’ when two or more pointers access the same memory location at the same time, where at least one of them is writing, and
the operations are not synchronised.
see also http://bit.ly/1F6WBVD
data race
a. two or more pointers to the same resource!b. at least one is writing!c. operations are not synchronised
see also http://bit.ly/1F6WBVD
Data Race Conditions!a. two or more pointers to the same resource!b. at least one is writing!c. operations are not synchronised
Borrowing Rules!one of the following, but not both:!
! 2.1 0 or more refs to a resource! ! 2.2 exactly 1 mutable ref
see also http://bit.ly/1F6WBVD
Data Race Conditions!a. two or more pointers to the same resource!b. at least one is writing!c. operations are not synchronised
Borrowing Rules!one of the following, but not both:!
! 2.1 0 or more refs to a resource! ! 2.2 exactly 1 mutable ref
Dependent Types
Uniqueness Types
Bit Syntax
Borrowed Pointers
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Signals
Macros
Unit-of-Measure
Actor Model
seen generics?aka parametric polymorphism
List<T>
List<T>List<int> List<Cat>
List<string>
what if…
types that depend on arbitrary values?
Vect n avector of n elements of type a
zipWith : (a -> b -> c) -> Vect n a -> Vect n b -> Vect n c
zipWith f [] [] = [] zipWith f (x :: xs) (y :: ys) = f x y :: zipWith f xs ys
Type Driven Development
making invalid state UNREPRESENTABLE
Signals
Dependent Types
Uniqueness Types
Bit Syntax
Borrowed Pointers
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Macros
Unit-of-Measure
Actor Model
Function Reactive Programming
Value over Time
Time
Value
Signals
Move Up
Move Down
private var arrowKeyUp:Bool; private var arrowKeyDown:Bool; !private var platform1:Platform; private var platform2:Platform; private var ball:Ball;
function keyDown(event:KeyboardEvent):Void { if (currentGameState == Paused && event.keyCode == 32) { setGameState(Playing); } else if (event.keyCode == 38) { ! ! arrowKeyUp = true;! }else if (event.keyCode == 40) { ! ! arrowKeyDown = true;! } }
function keyUp(event:KeyboardEvent):Void { if (event.keyCode == 38) { ! ! arrowKeyUp = false;! } else if (event.keyCode == 40) { ! ! arrowKeyDown = false;! } }
function everyFrame(event:Event):Void { if(currentGameState == Playing){ if (arrowKeyUp) { platform1.y -= platformSpeed; } if (arrowKeyDown) { platform1.y += platformSpeed; } if (platform1.y < 5) platform1.y = 5; if (platform1.y > 395) platform1.y = 395; } }
function everyFrame(event:Event):Void { if(currentGameState == Playing){ if (arrowKeyUp) { platform1.y -= platformSpeed; } if (arrowKeyDown) { platform1.y += platformSpeed; } if (platform1.y < 5) !! ! ! platform1.y = 5;!! ! if (platform1.y > 395) !! ! ! platform1.y = 395;! } }
source files
state changes
source files execution
source files execution
mental model
input state new state behaviour
{ x; y } { x; y-speed }
{ x; y } { x; y+speed }
timer { x; y } { x; y } draw platform
… … … …
transformation
let y = f(x)
Imperative Functional
x.f()
mutation
transformations simplify problem
decomposition
Move Up
Move Down
type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
type alias Platform = {x:Int, y:Int}!defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
Keyboard.arrowsUP { x=0, y=1 } DOWN { x=0, y=-1 } LEFT { x=-1, y=0 } RIGHT { x=1, y=0 }
type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform!p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input
“I thought of objects being like biological cells and/or
individual computers on a network, only able to
communicate with messages.”
- Alan Kay
“OOP to me means only messaging, local retention and protection and hiding of state-
process, and extreme late-binding of all things.”
- Alan Kay
Borrowed Pointers
Actor Model
Bit Syntax
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Dependent Types
Uniqueness Types
Signals
Macros
Unit-of-Measure
actor model
actor
state mailbox
actors share nothing
actor
state mailboxactor
actor
state mailboxactor
processing!storage!
communication
loop (Map) ->! receive! {get, Key, Pid} ->! Pid ! maps:get(Key, Map, not_found),! loop(Map);! {set, Key, Value} ->! loop(maps:put(Key, Value, Map))! end.
loop (Map) ->! receive! {get, Key, Pid} ->! Pid ! maps:get(Key, Map, not_found),! loop(Map);! {set, Key, Value} ->! loop(maps:put(Key, Value, Map))! end.
loop (Map) ->! receive! {get, Key, Pid} ->! Pid ! maps:get(Key, Map, not_found),! loop(Map);! {set, Key, Value} ->! loop(maps:put(Key, Value, Map))! end.
loop (Map) ->! receive! {get, Key, Pid} ->! Pid ! maps:get(Key, Map, not_found),! loop(Map);! {set, Key, Value} ->! loop(maps:put(Key, Value, Map))! end.
client (N, Pid) ->! Pid ! {set, N, N},! Pid ! {get, N, self()},! receive! not_found -> io:format(“~p :-(~n”, [N]);! N -> io:format(“~p :-)~n”, [N]);! _ -> io:format(“~p …~n”, [N])! end.
client (N, Pid) ->! Pid ! {set, N, N},! Pid ! {get, N, self()},! receive! not_found -> io:format(“~p :-(~n”, [N]);! N -> io:format(“~p :-)~n”, [N]);! _ -> io:format(“~p …~n”, [N])! end.
client (N, Pid) ->! Pid ! {set, N, N},! Pid ! {get, N, self()},! receive! not_found -> io:format(“~p :-(~n”, [N]);! N -> io:format(“~p :-)~n”, [N]);! _ -> io:format(“~p …~n”, [N])! end.
start(N) ->! Kvs = spawn(mod, loop, [#{}]),! [spawn(mod, client, [X, Kvs]) ! || X <- lists:seq(1,N)].
actors are cheap
no locks!
need state?!talk to the actor!
location transparency
pre-emptive scheduling
makes you !THINK !
about !distributed systems
messaging promotes failure thinking
Distributed
Computing
Network is reliable!Latency is zero!
Bandwidth is infinite!Network is secure!
Topology doesn't change!There is one administrator!
Transport cost is zero!The network is homogeneous
8 fallacies of distributed computing
supervise & restart
http://www.ustream.tv/recorded/61443262
https://aphyr.com/posts
Borrowed Pointers
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Dependent Types
Uniqueness Types
Signals
Macros
Unit-of-Measure
Bit Syntax
Actor Model
pattern matching
{ X, Y } = { 1, 2 }
{ X, Y } = { 1, 2 }
[ H | T ] = [ 1, 2, 3 ]
[ H | T ] = [ 1, 2, 3 ]
what if…
you can pattern match binary data?!e.g. TCP payload
<<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
<<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
<<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
<<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
<<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
.!
.!
.
<<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
case Packet of! <<SeqNum:16/big-unsigned-integer, ! Timestamp:32/big-unsigned-integer, ! Src:32/little-signed-integer, ! _/binary>> ->!! % do something useful!! …! _ ->!! % invalid format!! …!end
case Packet of! <<SeqNum:16/big-unsigned-integer, ! Timestamp:32/big-unsigned-integer, ! Src:32/little-signed-integer, ! _/binary>> ->!! % do something useful!! …! _ ->!! % invalid format!! …!end
case Packet of! <<SeqNum:16/big-unsigned-integer, ! Timestamp:32/big-unsigned-integer, ! Src:32/little-signed-integer, ! _/binary>> ->!! % do something useful!! …! _ ->!! % invalid format!! …!end
case Packet of! <<SeqNum:16/big-unsigned-integer, ! Timestamp:32/big-unsigned-integer, ! Src:32/little-signed-integer, ! _/binary>> ->!! % do something useful!! …! _ ->!! % invalid format!! …!end
case Packet of! <<SeqNum:16/big-unsigned-integer, ! Timestamp:32/big-unsigned-integer, ! Src:32/little-signed-integer, ! _/binary>> ->!! % do something useful!! …! _ ->!! % invalid format!! …!end
Type Provider Pipes
Statically Resolved TP Implicit Interface Implementation
Borrowed Pointers Dependent Types
Uniqueness TypesOTP
Bit SyntaxSignals
Macros
Unit-of-Measure
10,000 hours to reach top of an ultra-
competitive field
see also http://bit.ly/1KN7SLq
1.Deconstruct the skill!2.Learn enough to self-correct
see also http://bit.ly/1KN7SLq
1.Deconstruct the skill!2.Learn enough to self-correct!3.Remove practice barriers
see also http://bit.ly/1KN7SLq
1.Deconstruct the skill!2.Learn enough to self-correct!3.Remove practice barriers!4.Practice at least 20 hrs
see also http://bit.ly/1KN7SLq
logic programming
stack-oriented programming
array programming
“A language that doesn't affect the way you think
about programming, is not worth knowing.”
- Alan Perlis
Enterprise Tic-Tac-Toe - a Functional Approach
Type Driven Development
Computation expression in context : a history of the otter king
Learning From Haskell
“Learning is an act of creation itself, because something happens in you that wasn't
there before.”
- Alan Kay
@theburningmonktheburningmonk.comgithub.com/theburningmonk
@theburningmonktheburningmonk.comgithub.com/theburningmonk
WE’RE HIRINGwww.gamesyscorporate.com/careers
top related