Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
tour guide : Yan Cui @theburningmonk
Hi, my name is Yan Cui.
agenda
Type Provider Pipes
Statically Resolved TP
Implicit Interface
Implementation
Borrowed Pointers Dependent Types
Uniqueness ...
disclaimers
“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....
“The limits of my
language means the limits
of my world.”
- Ludwig Wittgenstein
“We cannot solve our
problems with the same
thinking we used when
we created them.”
- Albert Einstein
Type Provider Pipes
Statically Resolved TP
Implicit Interface
Implementation
Borrowed Pointers Dependent Types
Uniqueness ...
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
compiler
provideexternal
data source typed info
type providers
intellisense
tooltips
…
compile time validation
no code generation
R
FunScript
Azure
Amazon S3
CSVSQLite
SQL Server
WSDL
WorldBank
Regex
ODATA IKVM
Facebook
Apiary
XAMLFreebase
Hadoop
Oracl...
Type Provider Pipes
Statically Resolved TP
Implicit Interface
Implementation
Borrowed Pointers Dependent Types
Uniqueness ...
“…a clean design is one that
supports visual thinking so
people can meet their
informational needs with a
minimum of consc...
Whilst talking with an ex-colleague, a question came up on how to implement the Stable Marriage
problem using a message pa...
Whilst talking with an ex-colleague, a question came up on how to implement the Stable Marriage
problem using a message pa...
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
...
Whilst talking with an ex-colleague, a question came up on
how to implement the Stable Marriage problem using a
message pa...
“…a clean design is one that
supports visual thinking so
people can meet their
informational needs with a
minimum of consc...
|>
how we read CODE
let drawCircle x y radius =
radius |> circle
|> filled (rgb 150 170 150)
|> alpha 0.5
|> move (x, y)
see a...
how we read CODE
let drawCircle x y radius =
radius |> circle
|> filled (rgb 150 170 150)
|> alpha 0.5
|> move (x, y)
2.top...
let drawCircle x y radius =
circle radius
|> filled (rgb 150 170 150)
|> alpha 0.5
|> move (x, y)
see also http://bit.ly/1K...
let drawCircle x y radius =
circle radius
|> filled (rgb 150 170 150)
|> alpha 0.5
|> move (x, y)
see also http://bit.ly/1K...
let drawCircle x y radius =
circle radius
|> filled (rgb 150 170 150)
|> alpha 0.5
|> move (x, y)
see also http://bit.ly/1K...
Type Provider Pipes
Statically Resolved TP
Implicit Interface
Implementation
Borrowed Pointers Dependent Types
Uniqueness ...
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<Mete...
10<Meter> / 2<Second> = 5<Meter/Second>
10<Meter> * 2<Second> = 20<Meter Second>
10<Meter> + 10<Meter> = 20<Meter>
10<Mete...
Type Provider Pipes
Statically Resolved TP
Implicit Interface
Implementation
Borrowed Pointers Dependent Types
Uniqueness ...
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!
Convenience
Safety
what if…
Convenience Safety
see also http://bit.ly/1H2fN9i
implicit
interface
implementation
type Duck interface
{
Quack()
}
see also http://bit.ly/1ER5zVs
func sayQuack(duck Duck) {
duck.Quack()
}
see also http://bit.ly/1ER5zVs
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...
patterns are observed
after the fact
see also http://bit.ly/1ER5zVs
system building is also
a process of learning
and discovery
see also http://bit.ly/1ER5zVs
implementation
package
interface package
see also http://bit.ly/1ER5zVs
encourages precise
interface definitions
see also http://bit.ly/1ER5zVs
Type Provider Pipes
Statically Resolved TP
Implicit Interface
Implementation
Borrowed Pointers Dependent Types
Uniqueness ...
Homoiconicity
…homoiconicity is a property of some
programming languages in which the program
structure is similar to its ...
code is data
data is code
(let [x 1]
(inc x))
see also http://bit.ly/1PpIrjS
(let [x 1]
(inc x))
=> 2
see also http://bit.ly/1PpIrjS
list (1 2 3)
vector [1 2 3]
see also http://bit.ly/1PpIrjS
(let [x 1]
(inc x))
list
see also http://bit.ly/1PpIrjS
(let [x 1]
(inc x))
symbol
see also http://bit.ly/1PpIrjS
(let [x 1]
(inc x))
vector
see also http://bit.ly/1PpIrjS
(let [x 1]
(inc x))
list
see also http://bit.ly/1PpIrjS
form :
code as data structure
see also http://bit.ly/1PpIrjS
code data
quote
eval
see also http://bit.ly/1PpIrjS
quote
(+ 1 2)
=> 3
see also http://bit.ly/1PpIrjS
quote
(+ 1 2)
=> 3
(quote (+ 1 2))
=> (+ 1 2)
see also http://bit.ly/1PpIrjS
quote
(+ 1 2)
=> 3
(quote (+ 1 2))
=> (+ 1 2)
‘(+ 1 2)
=> (+ 1 2)
see also http://bit.ly/1PpIrjS
eval
‘(+ 1 2)
=> (+ 1 2)
(eval ‘(+ 1 2))
=> 3
see also http://bit.ly/1PpIrjS
macros
(defmacro assert-equals [actual expected]
‘(let [actual-val# ~actual]
(when-not (= actual-val# ~expected)
(throw
(Assertio...
(assert-equals (inc 1) 2) ; => nil
(assert-equals (inc 1) (+ 0 1))
; => AssertionError FAIL in (inc 1)
; expected: (+ 0 1)...
(assert-equals (inc 1) 2) ; => nil
(assert-equals (inc 1) (+ 0 1))
; => AssertionError FAIL in (inc 1)
; expected: (+ 0 1)...
(assert-equals (inc 1) 2) ; => nil
(assert-equals (inc 1) (+ 0 1))
; => AssertionError FAIL in (inc 1)
; expected: (+ 0 1)...
(defmacro assert-equals [actual expected]
‘(let [actual-val# ~actual]
(when-not (= actual-val# ~expected)
(throw
(Assertio...
(defmacro assert-equals [actual expected]
‘(let [actual-val# ~actual]
(when-not (= actual-val# ~expected)
(throw
(Assertio...
(defmacro assert-equals [actual expected]
‘(let [actual-val# ~actual]
(when-not (= actual-val# ~expected)
(throw
(Assertio...
see also http://bit.ly/1PpIrjS
(defmacro assert-equals [actual expected]
‘(let [actual-val# ~actual]
(when-not (= actual-v...
see also http://bit.ly/1PpIrjS
(defmacro assert-equals [actual expected]
‘(let [actual-val# ~actual]
(when-not (= actual-v...
expanded at
compile time
see also http://bit.ly/1PpIrjS
see also http://bit.ly/1PpIrjS
(macroexpand '(assert-equals (inc 1) (+ 0 1)))
; =>
; (let* [actual-value__16087__auto__ (i...
Type Provider Pipes
Statically Resolved TP
Implicit Interface
Implementation
Borrowed Pointers Dependent Types
Uniqueness ...
GC is great
runtime cost
ownership
see also http://bit.ly/1F6WBVD
memory safety
without GC
see also http://bit.ly/1F6WBVD
ZERO
runtime cost
see also http://bit.ly/1F6WBVD
safety + speed
see also http://bit.ly/1F6WBVD
fn foo() {
// v has ownership of the vector
let v = vec![1, 2, 3];
// mutable binding
let mut v2 = vec![];
}
// vector is ...
immutable by default
see also http://bit.ly/1F6WBVD
// take ownership
let v = vec![1, 2, 3];
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 ...
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 ...
see also http://bit.ly/1F6WBVD
see also http://bit.ly/1F6WBVD
let me buy
your book
see also http://bit.ly/1F6WBVD
sure thing!
see also http://bit.ly/1F6WBVD
thanks
see also http://bit.ly/1F6WBVD
BURN!!!
>:D
see also http://bit.ly/1F6WBVD
but I
still need it..
:’(
borrowing
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 ...
// take ownership
let v = vec![1, 2, 3];
// notice we're passing a reference,
// &v, instead of v
take(&v); // borrow owne...
see also http://bit.ly/1F6WBVD
let me
borrow your
book
see also http://bit.ly/1F6WBVD
sure thing!
see also http://bit.ly/1F6WBVD
thanks
see also http://bit.ly/1F6WBVD
I’m done,
here you go
see also http://bit.ly/1F6WBVD
thanks
see also http://bit.ly/1F6WBVD
immutable by default
fn take(v : &Vec<i32>) {
v.push(5);
}
let v = vec![];
take(&v);
// cannot borrow immutable borrowed
// content `*v` as mut...
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...
borrowing
rules
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 ...
see also http://bit.ly/1F6WBVD
data race
There is a ‘data race’ when two or more pointers
access the same memory location ...
see also http://bit.ly/1F6WBVD
data race
a. two or more pointers to the same resource
b. at least one is writing
c. operat...
see also http://bit.ly/1F6WBVD
Data Race Conditions
a. two or more pointers to the same resource
b. at least one is writin...
see also http://bit.ly/1F6WBVD
Data Race Conditions
a. two or more pointers to the same resource
b. at least one is writin...
see also http://bit.ly/1F6WBVD
Dependent Types
Uniqueness Types
Bit Syntax
Borrowed Pointers
Type Provider Pipes
Statically Resolved TP
Implicit Interfac...
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 a
vector 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
see also https://vimeo.com/123606435
Signals
Dependent Types
Uniqueness Types
Bit Syntax
Borrowed Pointers
Type Provider Pipes
Statically Resolved TP
Implicit ...
Functional 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...
function keyDown(event:KeyboardEvent):Void
{
if (currentGameState == Paused &&
event.keyCode == 32) {
setGameState(Playing...
function keyUp(event:KeyboardEvent):Void {
if (event.keyCode == 38) {
arrowKeyUp = false;
} else if (event.keyCode == 40) ...
function everyFrame(event:Event):Void {
if(currentGameState == Playing){
if (arrowKeyUp) {
platform1.y -= platformSpeed;
}...
function everyFrame(event:Event):Void {
if(currentGameState == Playing){
if (arrowKeyUp) {
platform1.y -= platformSpeed;
}...
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 ...
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 Keyboa...
type alias Platform = {x:Int, y:Int}
defaultPlatform = {x=5, y=0}
delta = Time.fps 20
input = Signal.sampleOn delta Keyboa...
type alias Platform = {x:Int, y:Int}
defaultPlatform = {x=5, y=0}
delta = Time.fps 20
input = Signal.sampleOn delta Keyboa...
Keyboard.arrows
UP { 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 Keyboa...
type alias Platform = {x:Int, y:Int}
defaultPlatform = {x=5, y=0}
delta = Time.fps 20
input = Signal.sampleOn delta Keyboa...
type alias Platform = {x:Int, y:Int}
defaultPlatform = {x=5, y=0}
delta = Time.fps 20
input = Signal.sampleOn delta Keyboa...
type alias Platform = {x:Int, y:Int}
defaultPlatform = {x=5, y=0}
delta = Time.fps 20
input = Signal.sampleOn delta Keyboa...
“I thought of objects being like
biological cells and/or
individual computers on a
network, only able to
communicate with ...
“OOP to me means only
messaging, local retention and
protection and hiding of state-
process, and extreme late-
binding of...
Borrowed Pointers
Actor Model
Bit Syntax
Type Provider Pipes
Statically Resolved TP
Implicit Interface
Implementation
Depe...
actor model
actor
state
mailbox
actors share nothing
actor
state
mailbox
actor
actor
state
mailbox
actor
processing
storage
communication
loop (Map) ->
receive
{get, Key, Pid} ->
Pid ! maps:get(Key, Map, not_found),
loop(Map);
{set, Key, Value} ->
loop(maps:pu...
loop (Map) ->
receive
{get, Key, Pid} ->
Pid ! maps:get(Key, Map, not_found),
loop(Map);
{set, Key, Value} ->
loop(maps:pu...
loop (Map) ->
receive
{get, Key, Pid} ->
Pid ! maps:get(Key, Map, not_found),
loop(Map);
{set, Key, Value} ->
loop(maps:pu...
loop (Map) ->
receive
{get, Key, Pid} ->
Pid ! maps:get(Key, Map, not_found),
loop(Map);
{set, Key, Value} ->
loop(maps:pu...
client (N, Pid) ->
Pid ! {set, N, N},
Pid ! {get, N, self()},
receive
not_found -> io:format(“~p :-(~n”, [N]);
N -> io:for...
client (N, Pid) ->
Pid ! {set, N, N},
Pid ! {get, N, self()},
receive
not_found -> io:format(“~p :-(~n”, [N]);
N -> io:for...
client (N, Pid) ->
Pid ! {set, N, N},
Pid ! {get, N, self()},
receive
not_found -> io:format(“~p :-(~n”, [N]);
N -> io:for...
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 administr...
supervise & restart
Type Provider Pipes
Statically Resolved TP
Implicit Interface
Implementation
Borrowed Pointers Dependent Types
Uniqueness ...
10,000 hours to be
good at something
see also http://bit.ly/1KN7SLq
10,000 hours to be
good at something
see also http://bit.ly/1KN7SLq
10,000 hours to reach
top of an ultra-
competitive field
see also http://bit.ly/1KN7SLq
the first 20 hours -
how to learn anything
see also http://bit.ly/1KN7SLq
Practice Time
Howgoodyouare
see also http://bit.ly/1KN7SLq
1.Deconstruct the skill
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...
learn a new paradigm
not a new syntax
see also http://bit.ly/1IzXVSo
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
see also http://bit.ly/1IzXVSo
see also http://bit.ly/1IzXVSo
“Learning is an act of creation
itself, because something
happens in you that wasn't
there before.”
- Alan Kay
@theburningmonk
theburningmonk.com
github.com/theburningmonk
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Tour of language landscape (code.talks)
Upcoming SlideShare
Loading in …5
×

Tour of language landscape (code.talks)

3,925 views

Published on

Tour of the programming landscape covering: F#, Go, Rust, Clojure, Elm and Idris.

Published in: Technology
  • Be the first to comment

Tour of language landscape (code.talks)

  1. 1. tour guide : Yan Cui @theburningmonk
  2. 2. Hi, my name is Yan Cui.
  3. 3. agenda
  4. 4. Type Provider Pipes Statically Resolved TP Implicit Interface Implementation Borrowed Pointers Dependent Types Uniqueness Types Bit Syntax Signals Macros Unit-of-Measure Actor Model
  5. 5. disclaimers
  6. 6. “Programming languages have a devious influence: they shape our thinking habits.” - Edsger W. Dijkstra
  7. 7. “One of the most disastrous thing we can learn is the first programming language, even if it's a good programming language.” - Alan Kay
  8. 8. “The limits of my language means the limits of my world.” - Ludwig Wittgenstein
  9. 9. “We cannot solve our problems with the same thinking we used when we created them.” - Albert Einstein
  10. 10. Type Provider Pipes Statically Resolved TP Implicit Interface Implementation Borrowed Pointers Dependent Types Uniqueness Types Bit Syntax Signals Macros Unit-of-Measure Actor Model
  11. 11. your app
  12. 12. your app CSVCSVCSV CSVCSVXML
  13. 13. your app CSVCSVCSV CSVCSVXML some service
  14. 14. your app CSVCSVCSV CSVCSVXML some service DB
  15. 15. 1. define DTO types 2. I/O 3. marshal data into DTO 4. do useful work
  16. 16. 1. define DTO types 2. I/O 3. marshal data into DTO 4. do useful work
  17. 17. compiler provideexternal data source typed info
  18. 18. type providers
  19. 19. intellisense tooltips …
  20. 20. compile time validation
  21. 21. no code generation
  22. 22. R FunScript Azure Amazon S3 CSVSQLite SQL Server WSDL WorldBank Regex ODATA IKVM Facebook Apiary XAMLFreebase Hadoop Oracle Minesweeper Don Syme Powershell JSON Fizzbuzz Mixin RSS Matlab Dates NorthPole XML Python
  23. 23. Type Provider Pipes Statically Resolved TP Implicit Interface Implementation Borrowed Pointers Dependent Types Uniqueness Types Bit Syntax Signals Macros Unit-of-Measure Actor Model
  24. 24. “…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)
  25. 25. 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
  26. 26. 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 see also http://bit.ly/1KN8cd0
  27. 27. how we read CODE public void DoSomething(int x, int y) { Foo(y, Bar(x, Zoo(Monkey()))); } see also http://bit.ly/1KN8cd0
  28. 28. 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
  29. 29. 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
  30. 30. “…a clean design is one that supports visual thinking so people can meet their informational needs with a minimum of conscious effort.”
  31. 31. |>
  32. 32. 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
  33. 33. 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-bottom 1.left-to-right see also http://bit.ly/1KN8cd0
  34. 34. let drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y) see also http://bit.ly/1KN8cd0
  35. 35. let drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y) see also http://bit.ly/1KN8cd0
  36. 36. let drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y) see also http://bit.ly/1KN8cd0
  37. 37. Type Provider Pipes Statically Resolved TP Implicit Interface Implementation Borrowed Pointers Dependent Types Uniqueness Types Bit Syntax Signals Macros Unit-of-Measure Actor Model
  38. 38. NASA orbiter crashed because one engineer accidentally used miles instead of kilometres
  39. 39. you’re never too smart to make mistakes
  40. 40. unit-of-measure
  41. 41. [<Measure>] type Pence e.g. 42<Pence> 153<Pence> …
  42. 42. 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
  43. 43. 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
  44. 44. Type Provider Pipes Statically Resolved TP Implicit Interface Implementation Borrowed Pointers Dependent Types Uniqueness Types Bit Syntax Signals Macros Unit-of-Measure Actor Model
  45. 45. Duck Typing If it looks like a duck and quacks like a duck, it's a duck
  46. 46. def say_quack(duck): duck.quack()
  47. 47. def say_quack(duck): duck.quack()
  48. 48. class Duck: def quack(self): print("quack quack!”)
  49. 49. class Duck: def quack(self): print("quack quack!”) duck = Duck() say_quack(duck) > quack quack!
  50. 50. class Bird: def quack(self): print(“tweet tweet!”)
  51. 51. class Bird: def quack(self): print(“tweet tweet!”) bird = Bird() say_quack(bird) > tweet tweet!
  52. 52. Convenience Safety
  53. 53. what if…
  54. 54. Convenience Safety see also http://bit.ly/1H2fN9i
  55. 55. implicit interface implementation
  56. 56. type Duck interface { Quack() } see also http://bit.ly/1ER5zVs
  57. 57. func sayQuack(duck Duck) { duck.Quack() } see also http://bit.ly/1ER5zVs
  58. 58. type Donald struct { } func (d Donald) Quack() { fmt.Println(“quack quack!”) } see also http://bit.ly/1ER5zVs
  59. 59. type Bird struct { } func (b Bird) Quack() { fmt.Println(“tweet tweet!”) } see also http://bit.ly/1ER5zVs
  60. 60. func main() { donald := Donald{} sayQuack(donald) bird := Bird{} sayQuack(bird) } see also http://bit.ly/1ER5zVs
  61. 61. quack quack! func main() { donald := Donald{} sayQuack(donald) bird := Bird{} sayQuack(bird) }
  62. 62. tweet tweet! func main() { donald := Donald{} sayQuack(donald) bird := Bird{} sayQuack(bird) }
  63. 63. type Dog struct { } func (d Dog) Bark() { fmt.Println(“woof woof!”) } see also http://bit.ly/1ER5zVs
  64. 64. 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
  65. 65. patterns are observed after the fact see also http://bit.ly/1ER5zVs
  66. 66. system building is also a process of learning and discovery see also http://bit.ly/1ER5zVs
  67. 67. implementation package interface package see also http://bit.ly/1ER5zVs
  68. 68. encourages precise interface definitions see also http://bit.ly/1ER5zVs
  69. 69. Type Provider Pipes Statically Resolved TP Implicit Interface Implementation Borrowed Pointers Dependent Types Uniqueness Types Bit Syntax Signals Macros Unit-of-Measure Actor Model
  70. 70. 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…
  71. 71. code is data data is code
  72. 72. (let [x 1] (inc x)) see also http://bit.ly/1PpIrjS
  73. 73. (let [x 1] (inc x)) => 2 see also http://bit.ly/1PpIrjS
  74. 74. list (1 2 3) vector [1 2 3] see also http://bit.ly/1PpIrjS
  75. 75. (let [x 1] (inc x)) list see also http://bit.ly/1PpIrjS
  76. 76. (let [x 1] (inc x)) symbol see also http://bit.ly/1PpIrjS
  77. 77. (let [x 1] (inc x)) vector see also http://bit.ly/1PpIrjS
  78. 78. (let [x 1] (inc x)) list see also http://bit.ly/1PpIrjS
  79. 79. form : code as data structure see also http://bit.ly/1PpIrjS
  80. 80. code data quote eval see also http://bit.ly/1PpIrjS
  81. 81. quote (+ 1 2) => 3 see also http://bit.ly/1PpIrjS
  82. 82. quote (+ 1 2) => 3 (quote (+ 1 2)) => (+ 1 2) see also http://bit.ly/1PpIrjS
  83. 83. quote (+ 1 2) => 3 (quote (+ 1 2)) => (+ 1 2) ‘(+ 1 2) => (+ 1 2) see also http://bit.ly/1PpIrjS
  84. 84. eval ‘(+ 1 2) => (+ 1 2) (eval ‘(+ 1 2)) => 3 see also http://bit.ly/1PpIrjS
  85. 85. macros
  86. 86. (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
  87. 87. (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
  88. 88. (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
  89. 89. (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?
  90. 90. (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
  91. 91. (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
  92. 92. (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
  93. 93. 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#))))))
  94. 94. 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#)))))) ‘(
  95. 95. expanded at compile time see also http://bit.ly/1PpIrjS
  96. 96. 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__)))))
  97. 97. Type Provider Pipes Statically Resolved TP Implicit Interface Implementation Borrowed Pointers Dependent Types Uniqueness Types Bit Syntax Signals Macros Unit-of-Measure Actor Model
  98. 98. GC is great
  99. 99. runtime cost
  100. 100. ownership see also http://bit.ly/1F6WBVD
  101. 101. memory safety without GC see also http://bit.ly/1F6WBVD
  102. 102. ZERO runtime cost see also http://bit.ly/1F6WBVD
  103. 103. safety + speed see also http://bit.ly/1F6WBVD
  104. 104. 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
  105. 105. immutable by default see also http://bit.ly/1F6WBVD
  106. 106. // take ownership let v = vec![1, 2, 3]; see also http://bit.ly/1F6WBVD
  107. 107. // take ownership let v = vec![1, 2, 3]; // moved ownership to v2 let v2 = v; see also http://bit.ly/1F6WBVD
  108. 108. // 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
  109. 109. fn take(v : Vec<i32>) { // ownership of vector transferred // to v in this scope } see also http://bit.ly/1F6WBVD
  110. 110. // take ownership let v = vec![1, 2, 3]; // moved ownership take(v); see also http://bit.ly/1F6WBVD
  111. 111. // 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
  112. 112. see also http://bit.ly/1F6WBVD
  113. 113. see also http://bit.ly/1F6WBVD let me buy your book
  114. 114. see also http://bit.ly/1F6WBVD sure thing!
  115. 115. see also http://bit.ly/1F6WBVD thanks
  116. 116. see also http://bit.ly/1F6WBVD BURN!!! >:D
  117. 117. see also http://bit.ly/1F6WBVD but I still need it.. :’(
  118. 118. borrowing see also http://bit.ly/1F6WBVD
  119. 119. // 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
  120. 120. // 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
  121. 121. see also http://bit.ly/1F6WBVD let me borrow your book
  122. 122. see also http://bit.ly/1F6WBVD sure thing!
  123. 123. see also http://bit.ly/1F6WBVD thanks
  124. 124. see also http://bit.ly/1F6WBVD I’m done, here you go
  125. 125. see also http://bit.ly/1F6WBVD thanks
  126. 126. see also http://bit.ly/1F6WBVD immutable by default
  127. 127. 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
  128. 128. 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
  129. 129. borrowing rules see also http://bit.ly/1F6WBVD
  130. 130. see also http://bit.ly/1F6WBVD Rule 1. the borrower’s scope must not outlast the owner
  131. 131. 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
  132. 132. 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.
  133. 133. 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
  134. 134. 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
  135. 135. 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
  136. 136. see also http://bit.ly/1F6WBVD
  137. 137. Dependent Types Uniqueness Types Bit Syntax Borrowed Pointers Type Provider Pipes Statically Resolved TP Implicit Interface Implementation Signals Macros Unit-of-Measure Actor Model
  138. 138. seen generics? aka parametric polymorphism
  139. 139. List<T>
  140. 140. List<T> List<int> List<Cat> List<string>
  141. 141. what if…
  142. 142. types that depend on arbitrary values?
  143. 143. Vect n a vector of n elements of type a
  144. 144. zipWith : (a -> b -> c) -> Vect n a -> Vect n b -> Vect n c
  145. 145. zipWith f [] [] = [] zipWith f (x :: xs) (y :: ys) = f x y :: zipWith f xs ys
  146. 146. Type Driven Development
  147. 147. making invalid state UNREPRESENTABLE
  148. 148. see also https://vimeo.com/123606435
  149. 149. Signals Dependent Types Uniqueness Types Bit Syntax Borrowed Pointers Type Provider Pipes Statically Resolved TP Implicit Interface Implementation Macros Unit-of-Measure Actor Model
  150. 150. Functional Reactive Programming
  151. 151. Value over Time
  152. 152. Time Value
  153. 153. Signals
  154. 154. Move Up Move Down
  155. 155. private var arrowKeyUp:Bool; private var arrowKeyDown:Bool; private var platform1:Platform; private var platform2:Platform; private var ball:Ball;
  156. 156. 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; } }
  157. 157. function keyUp(event:KeyboardEvent):Void { if (event.keyCode == 38) { arrowKeyUp = false; } else if (event.keyCode == 40) { arrowKeyDown = false; } }
  158. 158. 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; } }
  159. 159. 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; } }
  160. 160. source files state changes
  161. 161. source files execution
  162. 162. source files execution
  163. 163. mental model input state new state behaviour { x; y } { x; y-speed } { x; y } { x; y+speed } timer { x; y } { x; y } draw platform … … … …
  164. 164. transformation let y = f(x) Imperative Functional x.f() mutation
  165. 165. transformations simplify problem decomposition
  166. 166. Move Up Move Down
  167. 167. 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
  168. 168. 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
  169. 169. 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
  170. 170. Keyboard.arrows UP { x=0, y=1 } DOWN { x=0, y=-1 } LEFT { x=-1, y=0 } RIGHT { x=1, y=0 }
  171. 171. 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
  172. 172. 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
  173. 173. 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
  174. 174. 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
  175. 175. “I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages.” - Alan Kay
  176. 176. “OOP to me means only messaging, local retention and protection and hiding of state- process, and extreme late- binding of all things.” - Alan Kay
  177. 177. Borrowed Pointers Actor Model Bit Syntax Type Provider Pipes Statically Resolved TP Implicit Interface Implementation Dependent Types Uniqueness Types Signals Macros Unit-of-Measure
  178. 178. actor model
  179. 179. actor state mailbox
  180. 180. actors share nothing
  181. 181. actor state mailbox actor
  182. 182. actor state mailbox actor
  183. 183. processing storage communication
  184. 184. 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.
  185. 185. 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.
  186. 186. 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.
  187. 187. 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.
  188. 188. 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.
  189. 189. 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.
  190. 190. 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.
  191. 191. start(N) -> Kvs = spawn(mod, loop, [#{}]), [spawn(mod, client, [X, Kvs]) || X <- lists:seq(1,N)].
  192. 192. actors are cheap
  193. 193. no locks!
  194. 194. need state? talk to the actor!
  195. 195. location transparency
  196. 196. pre-emptive scheduling
  197. 197. makes you THINK about distributed systems
  198. 198. messaging promotes failure thinking
  199. 199. Distributed Computing
  200. 200. 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
  201. 201. supervise & restart
  202. 202. Type Provider Pipes Statically Resolved TP Implicit Interface Implementation Borrowed Pointers Dependent Types Uniqueness TypesOTP Bit Syntax Signals Macros Unit-of-Measure
  203. 203. 10,000 hours to be good at something see also http://bit.ly/1KN7SLq
  204. 204. 10,000 hours to be good at something see also http://bit.ly/1KN7SLq
  205. 205. 10,000 hours to reach top of an ultra- competitive field see also http://bit.ly/1KN7SLq
  206. 206. the first 20 hours - how to learn anything see also http://bit.ly/1KN7SLq
  207. 207. Practice Time Howgoodyouare see also http://bit.ly/1KN7SLq
  208. 208. 1.Deconstruct the skill see also http://bit.ly/1KN7SLq
  209. 209. 1.Deconstruct the skill 2.Learn enough to self-correct see also http://bit.ly/1KN7SLq
  210. 210. 1.Deconstruct the skill 2.Learn enough to self-correct 3.Remove practice barriers see also http://bit.ly/1KN7SLq
  211. 211. 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
  212. 212. learn a new paradigm not a new syntax see also http://bit.ly/1IzXVSo
  213. 213. logic programming
  214. 214. stack-oriented programming
  215. 215. array programming
  216. 216. “A language that doesn't affect the way you think about programming, is not worth knowing.” - Alan Perlis
  217. 217. see also http://bit.ly/1IzXVSo
  218. 218. see also http://bit.ly/1IzXVSo
  219. 219. “Learning is an act of creation itself, because something happens in you that wasn't there before.” - Alan Kay
  220. 220. @theburningmonk theburningmonk.com github.com/theburningmonk

×