SlideShare una empresa de Scribd logo
1 de 181
Descargar para leer sin conexión
The Pony Programming
Language
Andrew Turley
N Languages In N Months
October 4, 2016
About Me
Name
Andrew Turley
Contact
@casio_juarez / aturley@acm.org
Career
Currently at Sendence
What Is Pony?
What Is Pony?
“Pony is an open-source, object-oriented, actor-model, capabilities-secure, high
performance programming language.” -- ponylang.org
What Is Pony?
“Pony is an open-source, object-oriented, actor-model, capabilities-secure, high
performance programming language.” -- ponylang.org
BSD license
Copyright (c) 2014-2015, Causality Ltd.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
What Is Pony?
“Pony is an open-source, object-oriented, actor-model, capabilities-secure, high
performance programming language.” -- ponylang.org
Classes, Interfaces, Traits
(but they may work a little differently than you expect)
What Is Pony?
“Pony is an open-source, object-oriented, actor-model, capabilities-secure, high
performance programming language.” -- ponylang.org
Actors communicate by
passing messages to other
actors
What Is Pony?
“Pony is an open-source, object-oriented, actor-model, capabilities-secure, high
performance programming language.” -- ponylang.org
The compiler enforces what
you can and cannot do with
an object
What Is Pony?
“Pony is an open-source, object-oriented, actor-model, capabilities-secure, high
performance programming language.” -- ponylang.org
Uses LLVM to compile to
native code
What Is Pony?
“Pony is an open-source, object-oriented, actor-model, capabilities-secure, high
performance programming language.” -- ponylang.org
Also:
● powerful type system (unions, intersections,
parameterized types and functions)
● fast actor-based garbage collection system
hello.pony
hello.pony
actor Main
new create(env: Env) =>
env.out.print(“hello world”)
Thanks!
more-interesting.pony
more-interesting.pony
trait Shape
fun area(): F64
interface Named
fun name(): String
class Circle is Shape
let _radius: F64
new create(radius: F64) =>
_radius = radius
fun name(): String => "circle"
fun area(): F64 =>
3.14159 * _radius * _radius
class Square is Shape
let _side: F64
new create(side: F64) =>
_side = side
fun name(): String => "square"
fun area(): F64 =>
_side * _side
primitive AreaReporter
fun report(shape: (Shape & Named)): String =>
"The area of this " + shape.name() +
" is " + shape.area().string()
actor Main
new create(env: Env) =>
let s: F64 = 15.3
var area = AreaReporter.report(Circle(s))
env.out.print(area)
area = AreaReporter.report(Square(s))
env.out.print(area)
more-interesting.pony
trait Shape
fun area(): F64
interface Named
fun name(): String
class Circle is Shape
let _radius: F64
new create(radius: F64) =>
_radius = radius
fun name(): String => "circle"
fun area(): F64 =>
3.14159 * _radius * _radius
class Square is Shape
let _side: F64
new create(side: F64) =>
_side = side
fun name(): String => "square"
fun area(): F64 =>
_side * _side
primitive AreaReporter
fun report(shape: (Shape & Named)): String =>
"The area of this " + shape.name() +
" is " + shape.area().string()
actor Main
new create(env: Env) =>
let s: F64 = 15.3
var area = AreaReporter.report(Circle(s))
env.out.print(area)
area = AreaReporter.report(Square(s))
env.out.print(area)
more-interesting.pony
trait Shape
fun area(): F64
interface Named
fun name(): String
class Circle is Shape
let _radius: F64
new create(radius: F64) =>
_radius = radius
fun name(): String => "circle"
fun area(): F64 =>
3.14159 * _radius * _radius
class Square is Shape
let _side: F64
new create(side: F64) =>
_side = side
fun name(): String => "square"
fun area(): F64 =>
_side * _side
primitive AreaReporter
fun report(shape: (Shape & Named)): String =>
"The area of this " + shape.name() +
" is " + shape.area().string()
actor Main
new create(env: Env) =>
let s: F64 = 15.3
var area = AreaReporter.report(Circle(s))
env.out.print(area)
area = AreaReporter.report(Square(s))
env.out.print(area)
traits: nominal
subtyping
more-interesting.pony
trait Shape
fun area(): F64
interface Named
fun name(): String
class Circle is Shape
let _radius: F64
new create(radius: F64) =>
_radius = radius
fun name(): String => "circle"
fun area(): F64 =>
3.14159 * _radius * _radius
class Square is Shape
let _side: F64
new create(side: F64) =>
_side = side
fun name(): String => "square"
fun area(): F64 =>
_side * _side
primitive AreaReporter
fun report(shape: (Shape & Named)): String =>
"The area of this " + shape.name() +
" is " + shape.area().string()
actor Main
new create(env: Env) =>
let s: F64 = 15.3
var area = AreaReporter.report(Circle(s))
env.out.print(area)
area = AreaReporter.report(Square(s))
env.out.print(area)
more-interesting.pony
trait Shape
fun area(): F64
interface Named
fun name(): String
class Circle is Shape
let _radius: F64
new create(radius: F64) =>
_radius = radius
fun name(): String => "circle"
fun area(): F64 =>
3.14159 * _radius * _radius
class Square is Shape
let _side: F64
new create(side: F64) =>
_side = side
fun name(): String => "square"
fun area(): F64 =>
_side * _side
primitive AreaReporter
fun report(shape: (Shape & Named)): String =>
"The area of this " + shape.name() +
" is " + shape.area().string()
actor Main
new create(env: Env) =>
let s: F64 = 15.3
var area = AreaReporter.report(Circle(s))
env.out.print(area)
area = AreaReporter.report(Square(s))
env.out.print(area)
interfaces:
structural
subtyping
more-interesting.pony
trait Shape
fun area(): F64
interface Named
fun name(): String
class Circle is Shape
let _radius: F64
new create(radius: F64) =>
_radius = radius
fun name(): String => "circle"
fun area(): F64 =>
3.14159 * _radius * _radius
class Square is Shape
let _side: F64
new create(side: F64) =>
_side = side
fun name(): String => "square"
fun area(): F64 =>
_side * _side
primitive AreaReporter
fun report(shape: (Shape & Named)): String =>
"The area of this " + shape.name() +
" is " + shape.area().string()
actor Main
new create(env: Env) =>
let s: F64 = 15.3
var area = AreaReporter.report(Circle(s))
env.out.print(area)
area = AreaReporter.report(Square(s))
env.out.print(area)
more-interesting.pony
trait Shape
fun area(): F64
interface Named
fun name(): String
class Circle is Shape
let _radius: F64
new create(radius: F64) =>
_radius = radius
fun name(): String => "circle"
fun area(): F64 =>
3.14159 * _radius * _radius
class Square is Shape
let _side: F64
new create(side: F64) =>
_side = side
fun name(): String => "square"
fun area(): F64 =>
_side * _side
primitive AreaReporter
fun report(shape: (Shape & Named)): String =>
"The area of this " + shape.name() +
" is " + shape.area().string()
actor Main
new create(env: Env) =>
let s: F64 = 15.3
var area = AreaReporter.report(Circle(s))
env.out.print(area)
area = AreaReporter.report(Square(s))
env.out.print(area)
more-interesting.pony
trait Shape
fun area(): F64
interface Named
fun name(): String
class Circle is Shape
let _radius: F64
new create(radius: F64) =>
_radius = radius
fun name(): String => "circle"
fun area(): F64 =>
3.14159 * _radius * _radius
class Square is Shape
let _side: F64
new create(side: F64) =>
_side = side
fun name(): String => "square"
fun area(): F64 =>
_side * _side
primitive AreaReporter
fun report(shape: (Shape & Named)): String =>
"The area of this " + shape.name() +
" is " + shape.area().string()
actor Main
new create(env: Env) =>
let s: F64 = 15.3
var area = AreaReporter.report(Circle(s))
env.out.print(area)
area = AreaReporter.report(Square(s))
env.out.print(area)
primitive: object
with no data and
only one
instance
more-interesting.pony
trait Shape
fun area(): F64
interface Named
fun name(): String
class Circle is Shape
let _radius: F64
new create(radius: F64) =>
_radius = radius
fun name(): String => "circle"
fun area(): F64 =>
3.14159 * _radius * _radius
class Square is Shape
let _side: F64
new create(side: F64) =>
_side = side
fun name(): String => "square"
fun area(): F64 =>
_side * _side
primitive AreaReporter
fun report(shape: (Shape & Named)): String =>
"The area of this " + shape.name() +
" is " + shape.area().string()
actor Main
new create(env: Env) =>
let s: F64 = 15.3
var area = AreaReporter.report(Circle(s))
env.out.print(area)
area = AreaReporter.report(Square(s))
env.out.print(area)
more-interesting.pony
trait Shape
fun area(): F64
interface Named
fun name(): String
class Circle is Shape
let _radius: F64
new create(radius: F64) =>
_radius = radius
fun name(): String => "circle"
fun area(): F64 =>
3.14159 * _radius * _radius
class Square is Shape
let _side: F64
new create(side: F64) =>
_side = side
fun name(): String => "square"
fun area(): F64 =>
_side * _side
primitive AreaReporter
fun report(shape: (Shape & Named)): String =>
"The area of this " + shape.name() +
" is " + shape.area().string()
actor Main
new create(env: Env) =>
let s: F64 = 15.3
var area = AreaReporter.report(Circle(s))
env.out.print(area)
area = AreaReporter.report(Square(s))
env.out.print(area)
> ./ponyc src/more-interesting
> ./more-interesting
The area of this circle is 735.415
The area of this square is 234.09
>
Pony: The Really Interesting Parts
Pony: The Really Interesting Parts
Pony uses actors and reference capabilities to allow the compiler to guarantee
that a program is data-race-free.
Pony: The Really Interesting Parts
Pony uses actors and reference capabilities to allow the compiler to guarantee
that a program is data-race-free.
Pony: The Really Interesting Parts
Pony uses actors and reference capabilities to allow the compiler to guarantee
that a program is data-race-free.
Pony: The Really Interesting Parts
Pony uses actors and reference capabilities to allow the compiler to guarantee
that a program is data-race-free.
Pony: The Really Interesting Parts
Pony uses actors and reference capabilities to allow the compiler to guarantee
that a program is data-race-free.
Pony: The Really Interesting Parts
Pony uses actors and reference capabilities to allow the compiler to guarantee
that a program is data-race-free.
Pony: The Really Interesting Parts
Pony uses actors and reference capabilities to allow the compiler to guarantee
that a program is
data-race-free.
Pony: The Really Interesting Parts
data-race-free
(this is the part you should remember)
Off To The Data Races!
Off To The Data Races!
Some pseudo code (not Pony) …
global int a = 0
function inc() {
for x in range(0, 1000001) {
a = a + 1
}
}
function main() {
inc()
print(“a = “ + a)
}
1000000
Off To The Data Races!
Some more pseudo code (not Pony) …
global int a = 0
function inc() {
for x in range(0, 1000001) {
a = a + 1
}
}
function main() {
thread thread1 = Thread(inc)
thread thread2 = Thread(inc)
thread1.run()
thread2.run()
thread1.join()
thread2.join()
print(“a = “ + a)
}
● Run “inc()” simultaneously in two
places
● wait for both runs to finish
● print the value of “a”
Off To The Data Races!
Some more pseudo code (not Pony) …
global int a = 0
function inc() {
for x in range(0, 1000001) {
a = a + 1
}
}
function main() {
thread thread1 = Thread(inc)
thread thread2 = Thread(inc)
thread1.run()
thread2.run()
thread1.join()
thread2.join()
print(“a = “ + a)
}
Expected (two threads each
incrementing a variable
1000000 times):
2000000
Off To The Data Races!
Some more pseudo code (not Pony) …
global int a = 0
function inc() {
for x in range(0, 1000001) {
a = a + 1
}
}
function main() {
thread thread1 = Thread(inc)
thread thread2 = Thread(inc)
thread1.run()
thread2.run()
thread1.join()
thread2.join()
print(“a = “ + a)
}
Expected:
2000000
Actual Run 1:
1987735
Actual Run 2:
1935010
Actual Run 3:
1941217
Off To The Data Races!
Some more pseudo code (not Pony) …
global int a = 0
function inc() {
for x in range(0, 1000001) {
a = a + 1
}
}
function main() {
thread thread1 = Thread(inc)
thread thread2 = Thread(inc)
thread1.run()
thread2.run()
thread1.join()
thread2.join()
print(“a = “ + a)
}
Expected:
2000000
Actual Run 1:
1987735
Actual Run 2:
1935010
Actual Run 3:
1941217
WHY?
Off To The Data Races!
In thread1 …
// get the value of “a”
// add 1 to that value
// write the new value back to “a”
a = a + 1
Meanwhile, in thread2...
// get the value of “a”
// add 1 to that value
// write the new value back to “a”
a = a + 1
a = 26
Off To The Data Races!
In thread1 …
// get the value of “a” 26
// add 1 to that value
// write the new value back to “a”
a = a + 1
Meanwhile, in thread2...
// get the value of “a” 26
// add 1 to that value
// write the new value back to “a”
a = a + 1
a = 26
Off To The Data Races!
In thread1 …
// get the value of “a” 26
// add 1 to that value 26 + 1 = 27
// write the new value back to “a”
a = a + 1
Meanwhile, in thread2...
// get the value of “a” 26
// add 1 to that value 26 + 1 = 27
// write the new value back to “a”
a = a + 1
a = 26
Off To The Data Races!
In thread1 …
// get the value of “a” 26
// add 1 to that value 26 + 1 = 27
// write the new value back to “a” a = 27
a = a + 1
Meanwhile, in thread2...
// get the value of “a” 26
// add 1 to that value 26 + 1 = 27
// write the new value back to “a” a = 27
a = a + 1
a = 27
Off To The Data Races!
In thread1 …
// get the value of “a” 26
// add 1 to that value 26 + 1 = 27
// write the new value back to “a” a = 27
a = a + 1
Meanwhile, in thread2...
// get the value of “a” 26
// add 1 to that value 26 + 1 = 27
// write the new value back to “a” a = 27
a = a + 1
a = 27
We wanted a = 28
Off To The Data Races!
In thread1 …
// get the value of “a” 26
// add 1 to that value 26 + 1 = 27
// write the new value back to “a” a = 27
a = a + 1
Meanwhile, in thread2...
// get the value of “a” 26
// add 1 to that value 26 + 1 = 27
// write the new value back to “a” a = 27
a = a + 1
a = 27
This may not happen every time, but each time it
happens it increases the error of the result.
We wanted a = 28
Off To The Data Races!
In thread1 …
// get the value of “a” 26
// add 1 to that value 26 + 1 = 27
// write the new value back to “a” a = 27
a = a + 1
Meanwhile, in thread2...
// get the value of “a” 26
// add 1 to that value 26 + 1 = 27
// write the new value back to “a” a = 27
a = a + 1
a = 27
This may not happen every time, but each time it
happens it increases the error of the result.
We wanted a = 28
“Shared mutable state is the root of all evil.”
-- several different people, all at the same time
Off To The Data Races!
Techniques various and sundry for avoiding data races ...
● Locks! → a unit of execution acquires a lock, no other unit of execution can
acquire the lock until it is released
○ C and C++
● Synchronized blocks/functions/methods! → somebody writes the locks for you
○ Java
● Everything is read-only! → don’t need to worry about writes anymore
○ Erlang
● There’s only one binding to an object at any time! → move, borrow, copy
○ Rust
Off To The Data Races!
Techniques various and sundry for avoiding data races ...
● Locks! → a unit of execution acquires a lock, no other unit of execution can
acquire the lock until it is released
○ C and C++
● Synchronized blocks/functions/methods! → somebody writes the locks for you
○ Java
● Everything is read-only! → don’t need to worry about writes anymore
○ Erlang
● There’s only one binding to an object at any time! → move, borrow, copy
○ Rust
WELL
ACTUALLYNope, save it until the end.
Leaving The Data Races
Leaving The Data Races
Pony uses two rules to avoid data races:
● The Read Rule: If an actor can read an object then no other actor can modify
that object
● The Write Rule: If an actor can modify an object then no other actor can read
or modify it
Actors
Actors
Actors store state and act on that state in response to messages
Actor
● state
● behaviors
● functions
Actors
message3
message4
message1
message2 }Queue
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
Actors
message3
message4
message1
message2 }Queue
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
Actors
Get next
message
message3
message4
message1
message2 }Queue
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
Actors
Get next
message
Process
message
message3
message4
message1
message2 }Queue
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
Actors
Get next
message
Process
message
Collect
garbage
message3
message4
message1
message2 }Queue
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
THE LIFE OF ACTOR
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
WHICH / ONE WHICH / ONE
Actors
Get next
message
Process
message
Collect
garbage
message3
message4
message1
message2 }Queue
Actors
actor Donald
be foo(x: Something) =>
bar(x)
fun bar(x: Something) =>
// do something …
actor Jessica
let _d: Donald = Donald
let _s: Something = Something
be baz() =>
_d.foo(_s)
Actors
actor Donald
be foo(x: Something) =>
bar(x)
fun bar(x: Something) =>
// do something …
actor Jessica
let _d: Donald = Donald
let _s: Something = Something
be baz() =>
_d.foo(_s)
“be” means
“behavior”, this is
what processes a
message
Actors
actor Donald
be foo(x: Something) =>
bar(x)
fun bar(x: Something) =>
// do something …
actor Jessica
let _d: Donald = Donald
let _s: Something = Something
be baz() =>
_d.foo(_s)
“fun” means
“function”, these
are run by the
actor as part of
processing the
message
Actors
actor Donald
be foo(x: Something) =>
bar(x)
fun bar(x: Something) =>
// do something …
actor Jessica
let _d: Donald = Donald
let _s: Something = Something
be baz() =>
_d.foo(_s)
An actor sends a
message to
another actor
using the
“<a>.<be>(...)”
syntax
Actors
actor Donald
be foo(x: Something) =>
bar(x)
fun bar(x: Something) =>
// do something …
actor Jessica
let _d: Donald = Donald
let _s: Something = Something
be baz() =>
_d.foo(_s)
When talking
about Pony,
“method” means
either a function
or a behavior.
Actors
a1.bar() a2.baz() a1.bar()
a3.dee() a4.doo() a3.doh()
a5.moo()
a8.fee() a7.foo()
a6.mee()
a7.fuz()
time
CPU1: thread1
CPU2: thread2
CPU3: thread3
CPU4: thread4
Actors run on
threads (1 thread
per CPU by
default)
Actors
a1.bar() a2.baz()1 a1.bar()
a3.dee() a4.doo() a3.doh()
a5.moo()
a8.fee() a7.foo()
a6.mee()
a7.fuz()
time
CPU1: thread1
CPU2: thread2
CPU3: thread3
CPU4: thread4
a2.baz()2
Behaviors cannot
be preempted
Actors
a1.bar() a2.baz() a1.bar()
a1.buz() a4.doo() a3.doh()
a5.moo()
a8.fee() a7.foo()
a6.mee()
a7.fuz()
time
CPU1: thread1
CPU2: thread2
CPU3: thread3
CPU4: thread4
Actors process
one message at a
time
Actors: An Example
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main
create(env)
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main
create(env)
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main e
create(“howdy”)
create(env)
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main e
create(env)
o
create(“howdy)
create(env)
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main
create(env)create(“howdy)
foo(o)
e
_text=”howdy”
o
_env=env
create(env)
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main e
_text=”howdy”
o
_env=env
foo(o)1
foo(o)2
create(env)
foo(o)1
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main e
_text=”ydwoh”
o
_env=env
foo(o)2
foo(o)1
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main e
_text=”ydwoh”
o
_env=env
foo(o)2 say(“ydwoh”)
say(“ydwoh”)foo(o)2
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main e
_text=”howdy”
o
_env=env
YDWOH
foo(o)2
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main e
_text=”howdy”
o
_env=env
say(“howdy”)
YDWOH
say(“howdy”)
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main e
_text=”howdy”
o
_env=env
YDWOH
HOWDY
Actors: An Example
actor Example
var _text: String
new create(text: String) =>
_text = text
be foo(o: Other) =>
o.say(rev())
fun ref rev(): String val =>
_text = recover
_text.reverse()
end
_text
actor Other
let _env: Env
new create(env: Env) =>
_env = env
be say(s: String) =>
_env.out.print(s)
actor Main
new create(env: Env) =>
let e = Example("howdy")
let o = Other(env)
e.foo(o) // prints “ydwoh”
e.foo(o) // prints “howdy”
Main e
_text=”howdy”
o
_env=env
YDWOH
HOWDY
Backpressure?
Backpressure?
“How does Pony
handle
backpressure?”
Backpressure?
“How does Pony
handle
backpressure?”
“We’re working on it”
Reference Capabilities
Reference Capabilities
Remember the Read Rule and the Write Rule:
● The Read Rule: If an actor can read an object then no other actor can modify
that object
● The Write Rule: If an actor can modify an object then no other actor can read
or modify it
Reference Capabilities
class Foo
class val Bar
let v: U32
new val create(vv: U32) =>
v = vv
actor Main
new create(env: Env) =>
let a: Foo iso = recover Foo end
var b = Bar(1)
b = Bar(2)
baz(b)
fun baz(c: Bar): U32 =>
c.v + 16
Reference Capabilities
SPOT THE REFERENCE
CAPABILITIES!
class Foo
class val Bar
let v: U32
new val create(vv: U32) =>
v = vv
actor Main
new create(env: Env) =>
let a: Foo iso = recover Foo end
var b = Bar(1)
b = Bar(2)
baz(b)
fun baz(c: Bar): U32 =>
c.v + 16
Reference Capabilities
SPOT THE EXPLICIT REFERENCE
CAPABILITIES!
SPOT THE IMPLIED REFERENCE
CAPABILITIES!
class ref Foo
class val Bar
let v: U32 val
new val create(vv: U32 val) =>
v = vv
actor tag Main
new create(env: Env val) =>
let a: Foo iso = recover iso
Foo
end
var b: Bar val = Bar(1)
b = Bar(2)
baz(b)
fun box baz(c: Bar val): U32 val =>
c.v + 16
Reference Capabilities
Actors have a default reference
capability of tag, objects created
from classes have a default reference
capability of ref
You can change the implicit reference
capability of a class (normally it is
ref)
You can change the reference
capability of the object generated by
the constructor (normally it is ref)
class ref Foo
class val Bar
let v: U32 val
new val create(vv: U32 val) =>
v = vv
actor tag Main
new create(env: Env val) =>
let a: Foo iso = recover iso
Foo
end
var b: Bar val = Bar(1)
b = Bar(2)
baz(b)
fun box baz(c: Bar val): U32 val =>
c.v + 16
Reference Capabilities
You can specify the type of reference
capability that the receiver must have
to call a function
class ref Foo
class val Bar
let v: U32 val
new val create(vv: U32 val) =>
v = vv
actor tag Main
new create(env: Env val) =>
let a: Foo iso = recover iso
Foo
end
var b: Bar val = Bar(1)
b = Bar(2)
baz(b)
fun box baz(c: Bar val): U32 val =>
c.v + 16
Reference Capabilities
You can specify the type of reference
capability that the receiver must have
to call a function
This can get really tricky!
class ref Foo
class val Bar
let v: U32 val
new val create(vv: U32 val) =>
v = vv
actor tag Main
new create(env: Env val) =>
let a: Foo iso = recover iso
Foo
end
var b: Bar val = Bar(1)
b = Bar(2)
baz(b)
fun box baz(c: Bar val): U32 val =>
c.v + 16
Reference Capabilities
You can specify the type of reference
capability that the receiver must have
to call a function
This can get really tricky!
class ref Foo
class val Bar
let v: U32 val
new val create(vv: U32 val) =>
v = vv
actor tag Main
new create(env: Env val) =>
let a: Foo iso = recover iso
Foo
end
var b: Bar val = Bar(1)
b = Bar(2)
baz(b)
fun box baz(c: Bar val): U32 val =>
c.v + 16
Reference Capabilities
An alias is a name given to a particular object in
memory
Aliases are created when
● an object is assigned to a variable
● an object is passed as an argument to a
method
class Foo
class val Bar
let v: U32
new val create(vv: U32) =>
v = vv
actor Main
new create(env: Env) =>
let a: Foo iso = recover Foo end
var b = Bar(1)
b = Bar(2)
baz(b)
fun baz(c: Bar): U32 =>
c.v + 16
Reference Capabilities
An alias is a name given to a particular object in
memory
Aliases are created when
● an object is assigned to a variable
● an object is passed as an argument to a
method
class Foo
class val Bar
let v: U32
new val create(vv: U32) =>
v = vv
actor Main
new create(env: Env) =>
let a: Foo iso = recover Foo end
var b = Bar(1)
b = Bar(2)
baz(b)
fun baz(c: Bar): U32 =>
c.v + 16
Reference Capabilities
An alias is a name given to a particular object in
memory
Aliases are created when
● an object is assigned to a variable
● an object is passed as an argument to a
method
class Foo
class val Bar
let v: U32
new val create(vv: U32) =>
v = vv
actor Main
new create(env: Env) =>
let a: Foo iso = recover Foo end
var b = Bar(1)
b = Bar(2)
baz(b)
fun baz(c: Bar): U32 =>
c.v + 16
Reference Capabilities
An alias is a name given to a particular object in
memory
Aliases are created when
● an object is assigned to a variable
● an object is passed as an argument to a
method
class Foo
class val Bar
let v: U32
new val create(vv: U32) =>
v = vv
actor Main
new create(env: Env) =>
let a: Foo iso = recover Foo end
var b = Bar(1)
b = Bar(2)
baz(b)
fun baz(c: Bar): U32 =>
c.v + 16
Reference Capabilities
An alias is a name given to a particular object in
memory
Aliases are created when
● an object is assigned to a variable
● an object is passed as an argument to a
method
class Foo
class val Bar
let v: U32
new val create(vv: U32) =>
v = vv
actor Main
new create(env: Env) =>
let a: Foo iso = recover Foo end
var b = Bar(1)
b = Bar(2)
baz(b)
fun baz(c: Bar): U32 =>
c.v + 16
Reference Capabilities
An object may have more than one alias,
possibly in more than one actor, but the
combination of aliases must not violate the read
rule and write rule.
● The Read Rule: If an actor can
read an object then no other
actor can modify that object
● The Write Rule: If an actor can
modify an object then no other
actor can read or modify it
class Foo
class val Bar
let v: U32
new val create(vv: U32) =>
v = vv
actor Main
new create(env: Env) =>
let a: Foo iso = recover Foo end
var b = Bar(1)
b = Bar(2)
baz(b)
fun baz(c: Bar): U32 =>
c.v + 16
Reference Capabilities: A Visual Guide
Reference Capabilities: A Visual Guide
A visual language
Reference Capabilities: A Visual Guide
object
object
(class or
actor)
A visual language
Reference Capabilities: A Visual Guide
object
alias
A visual language
Reference Capabilities: A Visual Guide
object
ref cap
reference
capability
A visual language
Reference Capabilities: A Visual Guide
object
actor boundary
ref cap
A visual language
Reference Capabilities: A Visual Guide
object
alias can
send
object a
message
ref cap
A visual language
Reference Capabilities: A Visual Guide
object
note: any
alias can
send an
actor a
message,
regardless of
reference
capability
ref cap
A visual language
Reference Capabilities: A Visual Guide
object
alias
can
read
object
ref cap
A visual language
Reference Capabilities: A Visual Guide
object
alias
can
modify
object
ref cap
A visual language
Reference Capabilities: A Visual Guide
object another
alias in
the actor
can read
object
ref cap
A visual language
Reference Capabilities: A Visual Guide
object
another
alias
outside
the actor
can read
object
ref cap
A visual language
Reference Capabilities: A Visual Guide
objectanother
alias
inside the
actor can
modify
object
ref cap
A visual language
Reference Capabilities: A Visual Guide
object
another
alias
outside
the actor
can
modify
object
ref cap
A visual language
Reference Capabilities: A Visual Guide
object
ref cap
A visual language
Reference Capabilities: A Visual Guide
object
ref cap
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
Reference Capabilities: iso (isolated)
iso
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
object
iso reference
can read and
modify an object.
No other
reference can
read or modify
the object.
Reference Capabilities: trn (transitional)
trn
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
object
trn reference
can read and
modify an object.
No other
reference can
modify the
object, but the
actor may have
other references
that can read the
object.
Reference Capabilities: ref (reference)
ref
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
object
ref reference
can read and
modify an object.
Other references
in the object may
be able to read
or modify the
object, but no
other actor may
have a reference
that can read or
modify it.
Reference Capabilities: val (value)
val
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
object
val reference
can read an
object. The actor
may have other
references that
can read the
object, and other
actors may have
references that
can read the
object, but no
actor may have
a reference that
can modify it.
Reference Capabilities: box (box)
box
OR
box
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
objectobject
Reference Capabilities: box (box)
box
OR
box
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
objectobject
This looks like a ref This looks like a val
Reference Capabilities: box (box)
box
OR
box
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
objectobject
A box capability is used when you want to create a new read-only
reference to an object that is either val or ref.
This looks like a ref This looks like a val
Reference Capabilities: box (box)
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X ???): I32 =>
x.v() + 1
What should the
reference capability
be?
Reference Capabilities: box (box)
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X ref): I32 =>
x.v() + 1
Reference Capabilities: box (box)
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X ref): I32 =>
x.v() + 1
ref doesn’t work
because a ref (x)
can’t alias a val (b)
Reference Capabilities: box (box)
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X ref): I32 =>
x.v() + 1
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X val): I32 =>
x.v() + 1
ref doesn’t work
because a ref (x)
can’t alias a val (b)
Reference Capabilities: box (box)
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X ref): I32 =>
x.v() + 1
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X val): I32 =>
x.v() + 1
ref doesn’t work
because a ref (x)
can’t alias a val (b)
val Doesn’t work
because a val (x)
can’t alias a ref (a)
Reference Capabilities: box (box)
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X ref): I32 =>
x.v() + 1
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X val): I32 =>
x.v() + 1
ref doesn’t work
because a ref (x)
can’t alias a val (b)
val Doesn’t work
because a val (x)
can’t alias a ref (a)
Reference Capabilities: box (box)
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X ref): I32 =>
x.v() + 1
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X val): I32 =>
x.v() + 1
ref doesn’t work
because a ref (x)
can’t alias a val (b)
val Doesn’t work
because a val (x)
can’t alias a ref (a)
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X box): I32 =>
x.v() + 1
Reference Capabilities: box (box)
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X ref): I32 =>
x.v() + 1
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X val): I32 =>
x.v() + 1
ref doesn’t work
because a ref (x)
can’t alias a val (b)
val Doesn’t work
because a val (x)
can’t alias a ref (a)
class X
let v: I32
new create(v': I32) =>
v = v'
actor Main
new create(env: Env) =>
let a: X ref = X(7)
let b: X val = recover
X(8)
end
bar(a)
bar(b)
fun bar(x: X box): I32 =>
x.v() + 1
box works because
a box (x) can alias
a ref (a) or a val (b)
Reference Capabilities: tag (tag)
tag
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
object
tag reference
cannot read or
modify an object,
but it can be
used to send the
object messages
if the object is an
actor. Other
references may
read or modify
the object as
long as they do
not violate the
Read Rule and
the Write Rule.
Reference Capabilities
Readable → iso, trn, ref, val, box
iso trn
ref val
boxbox
OR
tag
Reference Capabilities
Writeable → iso, trn, ref
iso trn
ref val
box box
OR
tag
Reference Capabilities
Sendable → iso, val, tag
Objects with sendable reference
capabilities can be sent to other
actors in messages
iso trn
ref val
box box
OR
tag
Reference Capabilities: Sending A val
class Bar
actor Foo
be baz(x: Bar val) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover val Bar end
f.baz(b)
Reference Capabilities: Sending A val
class Bar
actor Foo
be baz(x: Bar val) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover val Bar end
f.baz(b)
main
Reference Capabilities: Sending A val
class Bar
actor Foo
be baz(x: Bar val) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover val Bar end
f.baz(b)
Main Foo
foo
Reference Capabilities: Sending A val
class Bar
actor Foo
be baz(x: Bar val) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover val Bar end
f.baz(b)
Main Foo
f
Bar
b
Reference Capabilities: Sending A val
class Bar
actor Foo
be baz(x: Bar val) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover val Bar end
f.baz(b)
Main Foo
f
Bar
b
baz( )
Reference Capabilities: Sending A val
class Bar
actor Foo
be baz(x: Bar val) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover val Bar end
f.baz(b)
Main Foo
f
Bar
b
baz( )
x
Reference Capabilities: Sending A val
class Bar
actor Foo
be baz(x: Bar val) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover val Bar end
f.baz(b)
Main Foo
f
Bar
b x
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
Reference Capabilities: Sending A tag
actor Bar
actor Foo
be baz(x: Bar tag) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = Bar
f.baz(b)
Reference Capabilities: Sending A tag
actor Bar
actor Foo
be baz(x: Bar tag) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = Bar
f.baz(b)
An actor’s default
reference
capability is tag
Reference Capabilities: Sending A tag
actor Bar
actor Foo
be baz(x: Bar tag) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = Bar
f.baz(b)
main
Reference Capabilities: Sending A tag
actor Bar
actor Foo
be baz(x: Bar tag) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = Bar
f.baz(b)
Main Foo
foo
Reference Capabilities: Sending A tag
actor Bar
actor Foo
be baz(x: Bar tag) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = Bar
f.baz(b)
Main Foo
f
Bar
b
Reference Capabilities: Sending A tag
actor Bar
actor Foo
be baz(x: Bar tag) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = Bar
f.baz(b)
Main Foo
f
Bar
b
baz( )
Reference Capabilities: Sending A tag
actor Bar
actor Foo
be baz(x: Bar tag) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = Bar
f.baz(b)
Main Foo
f
Bar
b
baz( )
x
Reference Capabilities: Sending A tag
actor Bar
actor Foo
be baz(x: Bar tag) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = Bar
f.baz(b)
Main Foo
f
Bar
b x
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
Reference Capabilities: Sending An iso
class Bar
actor Foo
be baz(x: Bar iso) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover iso Bar end
f.baz(consume b)
Reference Capabilities: Sending An iso
class Bar
actor Foo
be baz(x: Bar iso) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover iso Bar end
f.baz(consume b)
main
Reference Capabilities: Sending An iso
class Bar
actor Foo
be baz(x: Bar iso) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover iso Bar end
f.baz(consume b)
Main Foo
foo
Reference Capabilities: Sending An iso
class Bar
actor Foo
be baz(x: Bar iso) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover iso Bar end
f.baz(consume b)
Main Foo
f
Bar
b
Reference Capabilities: Sending An iso
class Bar
actor Foo
be baz(x: Bar iso) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover iso Bar end
f.baz(consume b)
Main Foo
f
Bar
b
consume
causes b to
give up it’s
reference
Reference Capabilities: Sending An iso
class Bar
actor Foo
be baz(x: Bar iso) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover iso Bar end
f.baz(consume b)
Main Foo
f
Bar
b
once we
consume b,
we can no
longer use it
Reference Capabilities: Sending An iso
class Bar
actor Foo
be baz(x: Bar iso) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover iso Bar end
f.baz(consume b)
Main Foo
f
Bar
b
baz( )
Reference Capabilities: Sending An iso
class Bar
actor Foo
be baz(x: Bar iso) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover iso Bar end
f.baz(consume b)
Main Foo
f
Bar
b
baz( )
x
Reference Capabilities: Sending An iso
class Bar
actor Foo
be baz(x: Bar iso) =>
// do something with x
actor Main
new create(env: Env) =>
let f = Foo
let b = recover iso Bar end
f.baz(consume b)
Main Foo
f
Bar
b x
● The Read Rule: If an
actor can read an
object then no other
actor can modify that
object
● The Write Rule: If an
actor can modify an
object then no other
actor can read or
modify it
No More Data Races
No More Data Races
use “collections”
actor Counter
var _count: U64 = 0
be increment() =>
_count = _count + 1
be print(env: Env) =>
env.out.print(_count.string())
actor Incrementer
new create(counter: Counter, main: Main) =>
for x in Range(0, 1_000_001) do
counter.increment()
end
main.finished(this)
actor Main
let _finished_count = 0
let _counter: Counter = Counter
let _env: Env
new create(env: Env) =>
_env = env
let inc1 = Incrementer(_counter, this)
let inc2 = Incrementer(_counter, this)
be finished() =>
_finished_count = _finished_count + 1
if _finished_count = 2 then
_counter.print(env)
end
No More Data Races
use “collections”
actor Counter
var _count: U64 = 0
be increment() =>
_count = _count + 1
be print(env: Env) =>
env.out.print(_count.string())
actor Incrementer
new create(counter: Counter, main: Main) =>
for x in Range(0, 1_000_001) do
counter.increment()
end
main.finished(this)
actor Main
let _finished_count = 0
let _counter: Counter = Counter
let _env: Env
new create(env: Env) =>
_env = env
let inc1 = Incrementer(_counter, this)
let inc2 = Incrementer(_counter, this)
be finished() =>
_finished_count = _finished_count + 1
if _finished_count = 2 then
_counter.print(env)
end
No More Data Races
use “collections”
actor Counter
var _count: U64 = 0
be increment() =>
_count = _count + 1
be print(env: Env) =>
env.out.print(_count.string())
actor Incrementer
new create(counter: Counter, main: Main) =>
for x in Range(0, 1_000_001) do
counter.increment()
end
main.finished(this)
actor Main
let _finished_count = 0
let _counter: Counter = Counter
let _env: Env
new create(env: Env) =>
_env = env
let inc1 = Incrementer(_counter, this)
let inc2 = Incrementer(_counter, this)
be finished() =>
_finished_count = _finished_count + 1
if _finished_count = 2 then
_counter.print(env)
end
No More Data Races
use “collections”
actor Counter
var _count: U64 = 0
be increment() =>
_count = _count + 1
be print(env: Env) =>
env.out.print(_count.string())
actor Incrementer
new create(counter: Counter, main: Main) =>
for x in Range(0, 1_000_001) do
counter.increment()
end
main.finished(this)
actor Main
let _finished_count = 0
let _counter: Counter = Counter
let _env: Env
new create(env: Env) =>
_env = env
let inc1 = Incrementer(_counter, this)
let inc2 = Incrementer(_counter, this)
be finished() =>
_finished_count = _finished_count + 1
if _finished_count = 2 then
_counter.print(env)
end
No More Data Races
use “collections”
actor Counter
var _count: U64 = 0
be increment() =>
_count = _count + 1
be print(env: Env) =>
env.out.print(_count.string())
actor Incrementer
new create(counter: Counter, main: Main) =>
for x in Range(0, 1_000_001) do
counter.increment()
end
main.finished(this)
actor Main
let _finished_count = 0
let _counter: Counter = Counter
let _env: Env
new create(env: Env) =>
_env = env
let inc1 = Incrementer(_counter, this)
let inc2 = Incrementer(_counter, this)
be finished() =>
_finished_count = _finished_count + 1
if _finished_count = 2 then
_counter.print(env)
end
No More Data Races
use “collections”
actor Counter
var _count: U64 = 0
be increment() =>
_count = _count + 1
be print(env: Env) =>
env.out.print(_count.string())
actor Incrementer
new create(counter: Counter, main: Main) =>
for x in Range(0, 1_000_001) do
counter.increment()
end
main.finished(this)
actor Main
let _finished_count = 0
let _counter: Counter = Counter
let _env: Env
new create(env: Env) =>
_env = env
let inc1 = Incrementer(_counter, this)
let inc2 = Incrementer(_counter, this)
be finished() =>
_finished_count = _finished_count + 1
if _finished_count = 2 then
_counter.print(env)
end
No More Data Races
use “collections”
actor Counter
var _count: U64 = 0
be increment() =>
_count = _count + 1
be print(env: Env) =>
env.out.print(_count.string())
actor Incrementer
new create(counter: Counter, main: Main) =>
for x in Range(0, 1_000_001) do
counter.increment()
end
main.finished(this)
actor Main
let _finished_count = 0
let _counter: Counter = Counter
let _env: Env
new create(env: Env) =>
_env = env
let inc1 = Incrementer(_counter, this)
let inc2 = Incrementer(_counter, this)
be finished() =>
_finished_count = _finished_count + 1
if _finished_count = 2 then
_counter.print(env)
end
No More Data Races
use “collections”
actor Counter
var _count: U64 = 0
be increment() =>
_count = _count + 1
be print(env: Env) =>
env.out.print(_count.string())
actor Incrementer
new create(counter: Counter, main: Main) =>
for x in Range(0, 1_000_001) do
counter.increment()
end
main.finished(this)
actor Main
let _finished_count = 0
let _counter: Counter = Counter
let _env: Env
new create(env: Env) =>
_env = env
let inc1 = Incrementer(_counter, this)
let inc2 = Incrementer(_counter, this)
be finished() =>
_finished_count = _finished_count + 1
if _finished_count = 2 then
_counter.print(env)
end
No More Data Races
use “collections”
actor Counter
var _count: U64 = 0
be increment() =>
_count = _count + 1
be print(env: Env) =>
env.out.print(_count.string())
actor Incrementer
new create(counter: Counter, main: Main) =>
for x in Range(0, 1_000_001) do
counter.increment()
end
main.finished(this)
actor Main
let _finished_count = 0
let _counter: Counter = Counter
let _env: Env
new create(env: Env) =>
_env = env
let inc1 = Incrementer(_counter, this)
let inc2 = Incrementer(_counter, this)
be finished() =>
_finished_count = _finished_count + 1
if _finished_count = 2 then
_counter.print(env)
end
2000000
No More Data Races
use “collections”
actor Counter
var _count: U64 = 0
be increment() =>
_count = _count + 1
be print(env: Env) =>
env.out.print(_count.string())
actor Incrementer
new create(counter: Counter, main: Main) =>
for x in Range(0, 1_000_001) do
counter.increment()
end
main.finished(this)
actor Main
let _finished_count = 0
let _counter: Counter = Counter
let _env: Env
new create(env: Env) =>
_env = env
let inc1 = Incrementer(_counter, this)
let inc2 = Incrementer(_counter, this)
be finished() =>
_finished_count = _finished_count + 1
if _finished_count = 2 then
_counter.print(env)
end
The Counter
actor “protects”
the _count data
structure
Sendence’s Experience With Pony
Sendence’s Experience With Pony
It’s nice to catch errors a compile time rather than runtime
Sendence’s Experience With Pony
It’s nice to catch errors a compile time rather than runtime
Pony is a young language (not even 1.0.0 yet)
Sendence’s Experience With Pony
It’s nice to catch errors a compile time rather than runtime
Pony is a young language (not even 1.0.0 yet)
● limited documentation
Sendence’s Experience With Pony
It’s nice to catch errors a compile time rather than runtime
Pony is a young language (not even 1.0.0 yet)
● limited documentation
● things change
Sendence’s Experience With Pony
It’s nice to catch errors a compile time rather than runtime
Pony is a young language (not even 1.0.0 yet)
● limited documentation
● things change
● there are some sharp edges (compiler bugs, runtime bugs)
Sendence’s Experience With Pony
It’s nice to catch errors a compile time rather than runtime
Pony is a young language (not even 1.0.0 yet)
● limited documentation
● things change
● there are some sharp edges (compiler bugs, runtime bugs)
“America is all about speed. Hot, nasty, badass speed.” -- Eleanor Roosevelt
PONY
Learn More
(because I left a lot out)
Learn More
User Mailing List
● https://pony.groups.io/g/user
Website
● https://www.ponylang.org
IRC
● freenode #ponylang
Contribute
Contribute
Developer Mailing List
● https://pony.groups.io/g/dev
Github
● Pony compiler → https://github.com/ponylang/ponyc
● RFCs → https://github.com/ponylang/rfcs
Thank You (Really)!
Questions

Más contenido relacionado

Último

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 

Último (20)

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 

Destacado

How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 

Destacado (20)

How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 

The Pony Programming Language

  • 1. The Pony Programming Language Andrew Turley N Languages In N Months October 4, 2016
  • 2. About Me Name Andrew Turley Contact @casio_juarez / aturley@acm.org Career Currently at Sendence
  • 4. What Is Pony? “Pony is an open-source, object-oriented, actor-model, capabilities-secure, high performance programming language.” -- ponylang.org
  • 5. What Is Pony? “Pony is an open-source, object-oriented, actor-model, capabilities-secure, high performance programming language.” -- ponylang.org BSD license Copyright (c) 2014-2015, Causality Ltd. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • 6. What Is Pony? “Pony is an open-source, object-oriented, actor-model, capabilities-secure, high performance programming language.” -- ponylang.org Classes, Interfaces, Traits (but they may work a little differently than you expect)
  • 7. What Is Pony? “Pony is an open-source, object-oriented, actor-model, capabilities-secure, high performance programming language.” -- ponylang.org Actors communicate by passing messages to other actors
  • 8. What Is Pony? “Pony is an open-source, object-oriented, actor-model, capabilities-secure, high performance programming language.” -- ponylang.org The compiler enforces what you can and cannot do with an object
  • 9. What Is Pony? “Pony is an open-source, object-oriented, actor-model, capabilities-secure, high performance programming language.” -- ponylang.org Uses LLVM to compile to native code
  • 10. What Is Pony? “Pony is an open-source, object-oriented, actor-model, capabilities-secure, high performance programming language.” -- ponylang.org Also: ● powerful type system (unions, intersections, parameterized types and functions) ● fast actor-based garbage collection system
  • 12. hello.pony actor Main new create(env: Env) => env.out.print(“hello world”)
  • 15. more-interesting.pony trait Shape fun area(): F64 interface Named fun name(): String class Circle is Shape let _radius: F64 new create(radius: F64) => _radius = radius fun name(): String => "circle" fun area(): F64 => 3.14159 * _radius * _radius class Square is Shape let _side: F64 new create(side: F64) => _side = side fun name(): String => "square" fun area(): F64 => _side * _side primitive AreaReporter fun report(shape: (Shape & Named)): String => "The area of this " + shape.name() + " is " + shape.area().string() actor Main new create(env: Env) => let s: F64 = 15.3 var area = AreaReporter.report(Circle(s)) env.out.print(area) area = AreaReporter.report(Square(s)) env.out.print(area)
  • 16. more-interesting.pony trait Shape fun area(): F64 interface Named fun name(): String class Circle is Shape let _radius: F64 new create(radius: F64) => _radius = radius fun name(): String => "circle" fun area(): F64 => 3.14159 * _radius * _radius class Square is Shape let _side: F64 new create(side: F64) => _side = side fun name(): String => "square" fun area(): F64 => _side * _side primitive AreaReporter fun report(shape: (Shape & Named)): String => "The area of this " + shape.name() + " is " + shape.area().string() actor Main new create(env: Env) => let s: F64 = 15.3 var area = AreaReporter.report(Circle(s)) env.out.print(area) area = AreaReporter.report(Square(s)) env.out.print(area)
  • 17. more-interesting.pony trait Shape fun area(): F64 interface Named fun name(): String class Circle is Shape let _radius: F64 new create(radius: F64) => _radius = radius fun name(): String => "circle" fun area(): F64 => 3.14159 * _radius * _radius class Square is Shape let _side: F64 new create(side: F64) => _side = side fun name(): String => "square" fun area(): F64 => _side * _side primitive AreaReporter fun report(shape: (Shape & Named)): String => "The area of this " + shape.name() + " is " + shape.area().string() actor Main new create(env: Env) => let s: F64 = 15.3 var area = AreaReporter.report(Circle(s)) env.out.print(area) area = AreaReporter.report(Square(s)) env.out.print(area) traits: nominal subtyping
  • 18. more-interesting.pony trait Shape fun area(): F64 interface Named fun name(): String class Circle is Shape let _radius: F64 new create(radius: F64) => _radius = radius fun name(): String => "circle" fun area(): F64 => 3.14159 * _radius * _radius class Square is Shape let _side: F64 new create(side: F64) => _side = side fun name(): String => "square" fun area(): F64 => _side * _side primitive AreaReporter fun report(shape: (Shape & Named)): String => "The area of this " + shape.name() + " is " + shape.area().string() actor Main new create(env: Env) => let s: F64 = 15.3 var area = AreaReporter.report(Circle(s)) env.out.print(area) area = AreaReporter.report(Square(s)) env.out.print(area)
  • 19. more-interesting.pony trait Shape fun area(): F64 interface Named fun name(): String class Circle is Shape let _radius: F64 new create(radius: F64) => _radius = radius fun name(): String => "circle" fun area(): F64 => 3.14159 * _radius * _radius class Square is Shape let _side: F64 new create(side: F64) => _side = side fun name(): String => "square" fun area(): F64 => _side * _side primitive AreaReporter fun report(shape: (Shape & Named)): String => "The area of this " + shape.name() + " is " + shape.area().string() actor Main new create(env: Env) => let s: F64 = 15.3 var area = AreaReporter.report(Circle(s)) env.out.print(area) area = AreaReporter.report(Square(s)) env.out.print(area) interfaces: structural subtyping
  • 20. more-interesting.pony trait Shape fun area(): F64 interface Named fun name(): String class Circle is Shape let _radius: F64 new create(radius: F64) => _radius = radius fun name(): String => "circle" fun area(): F64 => 3.14159 * _radius * _radius class Square is Shape let _side: F64 new create(side: F64) => _side = side fun name(): String => "square" fun area(): F64 => _side * _side primitive AreaReporter fun report(shape: (Shape & Named)): String => "The area of this " + shape.name() + " is " + shape.area().string() actor Main new create(env: Env) => let s: F64 = 15.3 var area = AreaReporter.report(Circle(s)) env.out.print(area) area = AreaReporter.report(Square(s)) env.out.print(area)
  • 21. more-interesting.pony trait Shape fun area(): F64 interface Named fun name(): String class Circle is Shape let _radius: F64 new create(radius: F64) => _radius = radius fun name(): String => "circle" fun area(): F64 => 3.14159 * _radius * _radius class Square is Shape let _side: F64 new create(side: F64) => _side = side fun name(): String => "square" fun area(): F64 => _side * _side primitive AreaReporter fun report(shape: (Shape & Named)): String => "The area of this " + shape.name() + " is " + shape.area().string() actor Main new create(env: Env) => let s: F64 = 15.3 var area = AreaReporter.report(Circle(s)) env.out.print(area) area = AreaReporter.report(Square(s)) env.out.print(area)
  • 22. more-interesting.pony trait Shape fun area(): F64 interface Named fun name(): String class Circle is Shape let _radius: F64 new create(radius: F64) => _radius = radius fun name(): String => "circle" fun area(): F64 => 3.14159 * _radius * _radius class Square is Shape let _side: F64 new create(side: F64) => _side = side fun name(): String => "square" fun area(): F64 => _side * _side primitive AreaReporter fun report(shape: (Shape & Named)): String => "The area of this " + shape.name() + " is " + shape.area().string() actor Main new create(env: Env) => let s: F64 = 15.3 var area = AreaReporter.report(Circle(s)) env.out.print(area) area = AreaReporter.report(Square(s)) env.out.print(area) primitive: object with no data and only one instance
  • 23. more-interesting.pony trait Shape fun area(): F64 interface Named fun name(): String class Circle is Shape let _radius: F64 new create(radius: F64) => _radius = radius fun name(): String => "circle" fun area(): F64 => 3.14159 * _radius * _radius class Square is Shape let _side: F64 new create(side: F64) => _side = side fun name(): String => "square" fun area(): F64 => _side * _side primitive AreaReporter fun report(shape: (Shape & Named)): String => "The area of this " + shape.name() + " is " + shape.area().string() actor Main new create(env: Env) => let s: F64 = 15.3 var area = AreaReporter.report(Circle(s)) env.out.print(area) area = AreaReporter.report(Square(s)) env.out.print(area)
  • 24. more-interesting.pony trait Shape fun area(): F64 interface Named fun name(): String class Circle is Shape let _radius: F64 new create(radius: F64) => _radius = radius fun name(): String => "circle" fun area(): F64 => 3.14159 * _radius * _radius class Square is Shape let _side: F64 new create(side: F64) => _side = side fun name(): String => "square" fun area(): F64 => _side * _side primitive AreaReporter fun report(shape: (Shape & Named)): String => "The area of this " + shape.name() + " is " + shape.area().string() actor Main new create(env: Env) => let s: F64 = 15.3 var area = AreaReporter.report(Circle(s)) env.out.print(area) area = AreaReporter.report(Square(s)) env.out.print(area) > ./ponyc src/more-interesting > ./more-interesting The area of this circle is 735.415 The area of this square is 234.09 >
  • 25. Pony: The Really Interesting Parts
  • 26. Pony: The Really Interesting Parts Pony uses actors and reference capabilities to allow the compiler to guarantee that a program is data-race-free.
  • 27. Pony: The Really Interesting Parts Pony uses actors and reference capabilities to allow the compiler to guarantee that a program is data-race-free.
  • 28. Pony: The Really Interesting Parts Pony uses actors and reference capabilities to allow the compiler to guarantee that a program is data-race-free.
  • 29. Pony: The Really Interesting Parts Pony uses actors and reference capabilities to allow the compiler to guarantee that a program is data-race-free.
  • 30. Pony: The Really Interesting Parts Pony uses actors and reference capabilities to allow the compiler to guarantee that a program is data-race-free.
  • 31. Pony: The Really Interesting Parts Pony uses actors and reference capabilities to allow the compiler to guarantee that a program is data-race-free.
  • 32. Pony: The Really Interesting Parts Pony uses actors and reference capabilities to allow the compiler to guarantee that a program is data-race-free.
  • 33. Pony: The Really Interesting Parts data-race-free (this is the part you should remember)
  • 34. Off To The Data Races!
  • 35. Off To The Data Races! Some pseudo code (not Pony) … global int a = 0 function inc() { for x in range(0, 1000001) { a = a + 1 } } function main() { inc() print(“a = “ + a) } 1000000
  • 36. Off To The Data Races! Some more pseudo code (not Pony) … global int a = 0 function inc() { for x in range(0, 1000001) { a = a + 1 } } function main() { thread thread1 = Thread(inc) thread thread2 = Thread(inc) thread1.run() thread2.run() thread1.join() thread2.join() print(“a = “ + a) } ● Run “inc()” simultaneously in two places ● wait for both runs to finish ● print the value of “a”
  • 37. Off To The Data Races! Some more pseudo code (not Pony) … global int a = 0 function inc() { for x in range(0, 1000001) { a = a + 1 } } function main() { thread thread1 = Thread(inc) thread thread2 = Thread(inc) thread1.run() thread2.run() thread1.join() thread2.join() print(“a = “ + a) } Expected (two threads each incrementing a variable 1000000 times): 2000000
  • 38. Off To The Data Races! Some more pseudo code (not Pony) … global int a = 0 function inc() { for x in range(0, 1000001) { a = a + 1 } } function main() { thread thread1 = Thread(inc) thread thread2 = Thread(inc) thread1.run() thread2.run() thread1.join() thread2.join() print(“a = “ + a) } Expected: 2000000 Actual Run 1: 1987735 Actual Run 2: 1935010 Actual Run 3: 1941217
  • 39. Off To The Data Races! Some more pseudo code (not Pony) … global int a = 0 function inc() { for x in range(0, 1000001) { a = a + 1 } } function main() { thread thread1 = Thread(inc) thread thread2 = Thread(inc) thread1.run() thread2.run() thread1.join() thread2.join() print(“a = “ + a) } Expected: 2000000 Actual Run 1: 1987735 Actual Run 2: 1935010 Actual Run 3: 1941217 WHY?
  • 40. Off To The Data Races! In thread1 … // get the value of “a” // add 1 to that value // write the new value back to “a” a = a + 1 Meanwhile, in thread2... // get the value of “a” // add 1 to that value // write the new value back to “a” a = a + 1 a = 26
  • 41. Off To The Data Races! In thread1 … // get the value of “a” 26 // add 1 to that value // write the new value back to “a” a = a + 1 Meanwhile, in thread2... // get the value of “a” 26 // add 1 to that value // write the new value back to “a” a = a + 1 a = 26
  • 42. Off To The Data Races! In thread1 … // get the value of “a” 26 // add 1 to that value 26 + 1 = 27 // write the new value back to “a” a = a + 1 Meanwhile, in thread2... // get the value of “a” 26 // add 1 to that value 26 + 1 = 27 // write the new value back to “a” a = a + 1 a = 26
  • 43. Off To The Data Races! In thread1 … // get the value of “a” 26 // add 1 to that value 26 + 1 = 27 // write the new value back to “a” a = 27 a = a + 1 Meanwhile, in thread2... // get the value of “a” 26 // add 1 to that value 26 + 1 = 27 // write the new value back to “a” a = 27 a = a + 1 a = 27
  • 44. Off To The Data Races! In thread1 … // get the value of “a” 26 // add 1 to that value 26 + 1 = 27 // write the new value back to “a” a = 27 a = a + 1 Meanwhile, in thread2... // get the value of “a” 26 // add 1 to that value 26 + 1 = 27 // write the new value back to “a” a = 27 a = a + 1 a = 27 We wanted a = 28
  • 45. Off To The Data Races! In thread1 … // get the value of “a” 26 // add 1 to that value 26 + 1 = 27 // write the new value back to “a” a = 27 a = a + 1 Meanwhile, in thread2... // get the value of “a” 26 // add 1 to that value 26 + 1 = 27 // write the new value back to “a” a = 27 a = a + 1 a = 27 This may not happen every time, but each time it happens it increases the error of the result. We wanted a = 28
  • 46. Off To The Data Races! In thread1 … // get the value of “a” 26 // add 1 to that value 26 + 1 = 27 // write the new value back to “a” a = 27 a = a + 1 Meanwhile, in thread2... // get the value of “a” 26 // add 1 to that value 26 + 1 = 27 // write the new value back to “a” a = 27 a = a + 1 a = 27 This may not happen every time, but each time it happens it increases the error of the result. We wanted a = 28 “Shared mutable state is the root of all evil.” -- several different people, all at the same time
  • 47. Off To The Data Races! Techniques various and sundry for avoiding data races ... ● Locks! → a unit of execution acquires a lock, no other unit of execution can acquire the lock until it is released ○ C and C++ ● Synchronized blocks/functions/methods! → somebody writes the locks for you ○ Java ● Everything is read-only! → don’t need to worry about writes anymore ○ Erlang ● There’s only one binding to an object at any time! → move, borrow, copy ○ Rust
  • 48. Off To The Data Races! Techniques various and sundry for avoiding data races ... ● Locks! → a unit of execution acquires a lock, no other unit of execution can acquire the lock until it is released ○ C and C++ ● Synchronized blocks/functions/methods! → somebody writes the locks for you ○ Java ● Everything is read-only! → don’t need to worry about writes anymore ○ Erlang ● There’s only one binding to an object at any time! → move, borrow, copy ○ Rust WELL ACTUALLYNope, save it until the end.
  • 50. Leaving The Data Races Pony uses two rules to avoid data races: ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it
  • 52. Actors Actors store state and act on that state in response to messages
  • 53. Actor ● state ● behaviors ● functions Actors message3 message4 message1 message2 }Queue
  • 54. THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE Actors message3 message4 message1 message2 }Queue
  • 55. THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE Actors Get next message message3 message4 message1 message2 }Queue
  • 56. THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE Actors Get next message Process message message3 message4 message1 message2 }Queue
  • 57. THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE Actors Get next message Process message Collect garbage message3 message4 message1 message2 }Queue
  • 58. THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR THE LIFE OF ACTOR WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE WHICH / ONE Actors Get next message Process message Collect garbage message3 message4 message1 message2 }Queue
  • 59. Actors actor Donald be foo(x: Something) => bar(x) fun bar(x: Something) => // do something … actor Jessica let _d: Donald = Donald let _s: Something = Something be baz() => _d.foo(_s)
  • 60. Actors actor Donald be foo(x: Something) => bar(x) fun bar(x: Something) => // do something … actor Jessica let _d: Donald = Donald let _s: Something = Something be baz() => _d.foo(_s) “be” means “behavior”, this is what processes a message
  • 61. Actors actor Donald be foo(x: Something) => bar(x) fun bar(x: Something) => // do something … actor Jessica let _d: Donald = Donald let _s: Something = Something be baz() => _d.foo(_s) “fun” means “function”, these are run by the actor as part of processing the message
  • 62. Actors actor Donald be foo(x: Something) => bar(x) fun bar(x: Something) => // do something … actor Jessica let _d: Donald = Donald let _s: Something = Something be baz() => _d.foo(_s) An actor sends a message to another actor using the “<a>.<be>(...)” syntax
  • 63. Actors actor Donald be foo(x: Something) => bar(x) fun bar(x: Something) => // do something … actor Jessica let _d: Donald = Donald let _s: Something = Something be baz() => _d.foo(_s) When talking about Pony, “method” means either a function or a behavior.
  • 64. Actors a1.bar() a2.baz() a1.bar() a3.dee() a4.doo() a3.doh() a5.moo() a8.fee() a7.foo() a6.mee() a7.fuz() time CPU1: thread1 CPU2: thread2 CPU3: thread3 CPU4: thread4 Actors run on threads (1 thread per CPU by default)
  • 65. Actors a1.bar() a2.baz()1 a1.bar() a3.dee() a4.doo() a3.doh() a5.moo() a8.fee() a7.foo() a6.mee() a7.fuz() time CPU1: thread1 CPU2: thread2 CPU3: thread3 CPU4: thread4 a2.baz()2 Behaviors cannot be preempted
  • 66. Actors a1.bar() a2.baz() a1.bar() a1.buz() a4.doo() a3.doh() a5.moo() a8.fee() a7.foo() a6.mee() a7.fuz() time CPU1: thread1 CPU2: thread2 CPU3: thread3 CPU4: thread4 Actors process one message at a time
  • 68. Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy”
  • 69. Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main create(env)
  • 70. Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main create(env)
  • 71. Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main e create(“howdy”) create(env)
  • 72. Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main e create(env) o create(“howdy) create(env)
  • 73. Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main create(env)create(“howdy) foo(o) e _text=”howdy” o _env=env create(env)
  • 74. Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main e _text=”howdy” o _env=env foo(o)1 foo(o)2 create(env)
  • 75. foo(o)1 Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main e _text=”ydwoh” o _env=env foo(o)2
  • 76. foo(o)1 Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main e _text=”ydwoh” o _env=env foo(o)2 say(“ydwoh”)
  • 77. say(“ydwoh”)foo(o)2 Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main e _text=”howdy” o _env=env YDWOH
  • 78. foo(o)2 Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main e _text=”howdy” o _env=env say(“howdy”) YDWOH
  • 79. say(“howdy”) Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main e _text=”howdy” o _env=env YDWOH HOWDY
  • 80. Actors: An Example actor Example var _text: String new create(text: String) => _text = text be foo(o: Other) => o.say(rev()) fun ref rev(): String val => _text = recover _text.reverse() end _text actor Other let _env: Env new create(env: Env) => _env = env be say(s: String) => _env.out.print(s) actor Main new create(env: Env) => let e = Example("howdy") let o = Other(env) e.foo(o) // prints “ydwoh” e.foo(o) // prints “howdy” Main e _text=”howdy” o _env=env YDWOH HOWDY
  • 85. Reference Capabilities Remember the Read Rule and the Write Rule: ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it
  • 86. Reference Capabilities class Foo class val Bar let v: U32 new val create(vv: U32) => v = vv actor Main new create(env: Env) => let a: Foo iso = recover Foo end var b = Bar(1) b = Bar(2) baz(b) fun baz(c: Bar): U32 => c.v + 16
  • 87. Reference Capabilities SPOT THE REFERENCE CAPABILITIES! class Foo class val Bar let v: U32 new val create(vv: U32) => v = vv actor Main new create(env: Env) => let a: Foo iso = recover Foo end var b = Bar(1) b = Bar(2) baz(b) fun baz(c: Bar): U32 => c.v + 16
  • 88. Reference Capabilities SPOT THE EXPLICIT REFERENCE CAPABILITIES! SPOT THE IMPLIED REFERENCE CAPABILITIES! class ref Foo class val Bar let v: U32 val new val create(vv: U32 val) => v = vv actor tag Main new create(env: Env val) => let a: Foo iso = recover iso Foo end var b: Bar val = Bar(1) b = Bar(2) baz(b) fun box baz(c: Bar val): U32 val => c.v + 16
  • 89. Reference Capabilities Actors have a default reference capability of tag, objects created from classes have a default reference capability of ref You can change the implicit reference capability of a class (normally it is ref) You can change the reference capability of the object generated by the constructor (normally it is ref) class ref Foo class val Bar let v: U32 val new val create(vv: U32 val) => v = vv actor tag Main new create(env: Env val) => let a: Foo iso = recover iso Foo end var b: Bar val = Bar(1) b = Bar(2) baz(b) fun box baz(c: Bar val): U32 val => c.v + 16
  • 90. Reference Capabilities You can specify the type of reference capability that the receiver must have to call a function class ref Foo class val Bar let v: U32 val new val create(vv: U32 val) => v = vv actor tag Main new create(env: Env val) => let a: Foo iso = recover iso Foo end var b: Bar val = Bar(1) b = Bar(2) baz(b) fun box baz(c: Bar val): U32 val => c.v + 16
  • 91. Reference Capabilities You can specify the type of reference capability that the receiver must have to call a function This can get really tricky! class ref Foo class val Bar let v: U32 val new val create(vv: U32 val) => v = vv actor tag Main new create(env: Env val) => let a: Foo iso = recover iso Foo end var b: Bar val = Bar(1) b = Bar(2) baz(b) fun box baz(c: Bar val): U32 val => c.v + 16
  • 92. Reference Capabilities You can specify the type of reference capability that the receiver must have to call a function This can get really tricky! class ref Foo class val Bar let v: U32 val new val create(vv: U32 val) => v = vv actor tag Main new create(env: Env val) => let a: Foo iso = recover iso Foo end var b: Bar val = Bar(1) b = Bar(2) baz(b) fun box baz(c: Bar val): U32 val => c.v + 16
  • 93. Reference Capabilities An alias is a name given to a particular object in memory Aliases are created when ● an object is assigned to a variable ● an object is passed as an argument to a method class Foo class val Bar let v: U32 new val create(vv: U32) => v = vv actor Main new create(env: Env) => let a: Foo iso = recover Foo end var b = Bar(1) b = Bar(2) baz(b) fun baz(c: Bar): U32 => c.v + 16
  • 94. Reference Capabilities An alias is a name given to a particular object in memory Aliases are created when ● an object is assigned to a variable ● an object is passed as an argument to a method class Foo class val Bar let v: U32 new val create(vv: U32) => v = vv actor Main new create(env: Env) => let a: Foo iso = recover Foo end var b = Bar(1) b = Bar(2) baz(b) fun baz(c: Bar): U32 => c.v + 16
  • 95. Reference Capabilities An alias is a name given to a particular object in memory Aliases are created when ● an object is assigned to a variable ● an object is passed as an argument to a method class Foo class val Bar let v: U32 new val create(vv: U32) => v = vv actor Main new create(env: Env) => let a: Foo iso = recover Foo end var b = Bar(1) b = Bar(2) baz(b) fun baz(c: Bar): U32 => c.v + 16
  • 96. Reference Capabilities An alias is a name given to a particular object in memory Aliases are created when ● an object is assigned to a variable ● an object is passed as an argument to a method class Foo class val Bar let v: U32 new val create(vv: U32) => v = vv actor Main new create(env: Env) => let a: Foo iso = recover Foo end var b = Bar(1) b = Bar(2) baz(b) fun baz(c: Bar): U32 => c.v + 16
  • 97. Reference Capabilities An alias is a name given to a particular object in memory Aliases are created when ● an object is assigned to a variable ● an object is passed as an argument to a method class Foo class val Bar let v: U32 new val create(vv: U32) => v = vv actor Main new create(env: Env) => let a: Foo iso = recover Foo end var b = Bar(1) b = Bar(2) baz(b) fun baz(c: Bar): U32 => c.v + 16
  • 98. Reference Capabilities An object may have more than one alias, possibly in more than one actor, but the combination of aliases must not violate the read rule and write rule. ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it class Foo class val Bar let v: U32 new val create(vv: U32) => v = vv actor Main new create(env: Env) => let a: Foo iso = recover Foo end var b = Bar(1) b = Bar(2) baz(b) fun baz(c: Bar): U32 => c.v + 16
  • 100. Reference Capabilities: A Visual Guide A visual language
  • 101. Reference Capabilities: A Visual Guide object object (class or actor) A visual language
  • 102. Reference Capabilities: A Visual Guide object alias A visual language
  • 103. Reference Capabilities: A Visual Guide object ref cap reference capability A visual language
  • 104. Reference Capabilities: A Visual Guide object actor boundary ref cap A visual language
  • 105. Reference Capabilities: A Visual Guide object alias can send object a message ref cap A visual language
  • 106. Reference Capabilities: A Visual Guide object note: any alias can send an actor a message, regardless of reference capability ref cap A visual language
  • 107. Reference Capabilities: A Visual Guide object alias can read object ref cap A visual language
  • 108. Reference Capabilities: A Visual Guide object alias can modify object ref cap A visual language
  • 109. Reference Capabilities: A Visual Guide object another alias in the actor can read object ref cap A visual language
  • 110. Reference Capabilities: A Visual Guide object another alias outside the actor can read object ref cap A visual language
  • 111. Reference Capabilities: A Visual Guide objectanother alias inside the actor can modify object ref cap A visual language
  • 112. Reference Capabilities: A Visual Guide object another alias outside the actor can modify object ref cap A visual language
  • 113. Reference Capabilities: A Visual Guide object ref cap A visual language
  • 114. Reference Capabilities: A Visual Guide object ref cap ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it
  • 115. Reference Capabilities: iso (isolated) iso ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it object iso reference can read and modify an object. No other reference can read or modify the object.
  • 116. Reference Capabilities: trn (transitional) trn ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it object trn reference can read and modify an object. No other reference can modify the object, but the actor may have other references that can read the object.
  • 117. Reference Capabilities: ref (reference) ref ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it object ref reference can read and modify an object. Other references in the object may be able to read or modify the object, but no other actor may have a reference that can read or modify it.
  • 118. Reference Capabilities: val (value) val ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it object val reference can read an object. The actor may have other references that can read the object, and other actors may have references that can read the object, but no actor may have a reference that can modify it.
  • 119. Reference Capabilities: box (box) box OR box ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it objectobject
  • 120. Reference Capabilities: box (box) box OR box ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it objectobject This looks like a ref This looks like a val
  • 121. Reference Capabilities: box (box) box OR box ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it objectobject A box capability is used when you want to create a new read-only reference to an object that is either val or ref. This looks like a ref This looks like a val
  • 122. Reference Capabilities: box (box) class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X ???): I32 => x.v() + 1 What should the reference capability be?
  • 123. Reference Capabilities: box (box) class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X ref): I32 => x.v() + 1
  • 124. Reference Capabilities: box (box) class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X ref): I32 => x.v() + 1 ref doesn’t work because a ref (x) can’t alias a val (b)
  • 125. Reference Capabilities: box (box) class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X ref): I32 => x.v() + 1 class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X val): I32 => x.v() + 1 ref doesn’t work because a ref (x) can’t alias a val (b)
  • 126. Reference Capabilities: box (box) class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X ref): I32 => x.v() + 1 class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X val): I32 => x.v() + 1 ref doesn’t work because a ref (x) can’t alias a val (b) val Doesn’t work because a val (x) can’t alias a ref (a)
  • 127. Reference Capabilities: box (box) class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X ref): I32 => x.v() + 1 class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X val): I32 => x.v() + 1 ref doesn’t work because a ref (x) can’t alias a val (b) val Doesn’t work because a val (x) can’t alias a ref (a)
  • 128. Reference Capabilities: box (box) class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X ref): I32 => x.v() + 1 class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X val): I32 => x.v() + 1 ref doesn’t work because a ref (x) can’t alias a val (b) val Doesn’t work because a val (x) can’t alias a ref (a) class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X box): I32 => x.v() + 1
  • 129. Reference Capabilities: box (box) class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X ref): I32 => x.v() + 1 class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X val): I32 => x.v() + 1 ref doesn’t work because a ref (x) can’t alias a val (b) val Doesn’t work because a val (x) can’t alias a ref (a) class X let v: I32 new create(v': I32) => v = v' actor Main new create(env: Env) => let a: X ref = X(7) let b: X val = recover X(8) end bar(a) bar(b) fun bar(x: X box): I32 => x.v() + 1 box works because a box (x) can alias a ref (a) or a val (b)
  • 130. Reference Capabilities: tag (tag) tag ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it object tag reference cannot read or modify an object, but it can be used to send the object messages if the object is an actor. Other references may read or modify the object as long as they do not violate the Read Rule and the Write Rule.
  • 131. Reference Capabilities Readable → iso, trn, ref, val, box iso trn ref val boxbox OR tag
  • 132. Reference Capabilities Writeable → iso, trn, ref iso trn ref val box box OR tag
  • 133. Reference Capabilities Sendable → iso, val, tag Objects with sendable reference capabilities can be sent to other actors in messages iso trn ref val box box OR tag
  • 134. Reference Capabilities: Sending A val class Bar actor Foo be baz(x: Bar val) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover val Bar end f.baz(b)
  • 135. Reference Capabilities: Sending A val class Bar actor Foo be baz(x: Bar val) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover val Bar end f.baz(b) main
  • 136. Reference Capabilities: Sending A val class Bar actor Foo be baz(x: Bar val) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover val Bar end f.baz(b) Main Foo foo
  • 137. Reference Capabilities: Sending A val class Bar actor Foo be baz(x: Bar val) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover val Bar end f.baz(b) Main Foo f Bar b
  • 138. Reference Capabilities: Sending A val class Bar actor Foo be baz(x: Bar val) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover val Bar end f.baz(b) Main Foo f Bar b baz( )
  • 139. Reference Capabilities: Sending A val class Bar actor Foo be baz(x: Bar val) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover val Bar end f.baz(b) Main Foo f Bar b baz( ) x
  • 140. Reference Capabilities: Sending A val class Bar actor Foo be baz(x: Bar val) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover val Bar end f.baz(b) Main Foo f Bar b x ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it
  • 141. Reference Capabilities: Sending A tag actor Bar actor Foo be baz(x: Bar tag) => // do something with x actor Main new create(env: Env) => let f = Foo let b = Bar f.baz(b)
  • 142. Reference Capabilities: Sending A tag actor Bar actor Foo be baz(x: Bar tag) => // do something with x actor Main new create(env: Env) => let f = Foo let b = Bar f.baz(b) An actor’s default reference capability is tag
  • 143. Reference Capabilities: Sending A tag actor Bar actor Foo be baz(x: Bar tag) => // do something with x actor Main new create(env: Env) => let f = Foo let b = Bar f.baz(b) main
  • 144. Reference Capabilities: Sending A tag actor Bar actor Foo be baz(x: Bar tag) => // do something with x actor Main new create(env: Env) => let f = Foo let b = Bar f.baz(b) Main Foo foo
  • 145. Reference Capabilities: Sending A tag actor Bar actor Foo be baz(x: Bar tag) => // do something with x actor Main new create(env: Env) => let f = Foo let b = Bar f.baz(b) Main Foo f Bar b
  • 146. Reference Capabilities: Sending A tag actor Bar actor Foo be baz(x: Bar tag) => // do something with x actor Main new create(env: Env) => let f = Foo let b = Bar f.baz(b) Main Foo f Bar b baz( )
  • 147. Reference Capabilities: Sending A tag actor Bar actor Foo be baz(x: Bar tag) => // do something with x actor Main new create(env: Env) => let f = Foo let b = Bar f.baz(b) Main Foo f Bar b baz( ) x
  • 148. Reference Capabilities: Sending A tag actor Bar actor Foo be baz(x: Bar tag) => // do something with x actor Main new create(env: Env) => let f = Foo let b = Bar f.baz(b) Main Foo f Bar b x ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it
  • 149. Reference Capabilities: Sending An iso class Bar actor Foo be baz(x: Bar iso) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover iso Bar end f.baz(consume b)
  • 150. Reference Capabilities: Sending An iso class Bar actor Foo be baz(x: Bar iso) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover iso Bar end f.baz(consume b) main
  • 151. Reference Capabilities: Sending An iso class Bar actor Foo be baz(x: Bar iso) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover iso Bar end f.baz(consume b) Main Foo foo
  • 152. Reference Capabilities: Sending An iso class Bar actor Foo be baz(x: Bar iso) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover iso Bar end f.baz(consume b) Main Foo f Bar b
  • 153. Reference Capabilities: Sending An iso class Bar actor Foo be baz(x: Bar iso) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover iso Bar end f.baz(consume b) Main Foo f Bar b consume causes b to give up it’s reference
  • 154. Reference Capabilities: Sending An iso class Bar actor Foo be baz(x: Bar iso) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover iso Bar end f.baz(consume b) Main Foo f Bar b once we consume b, we can no longer use it
  • 155. Reference Capabilities: Sending An iso class Bar actor Foo be baz(x: Bar iso) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover iso Bar end f.baz(consume b) Main Foo f Bar b baz( )
  • 156. Reference Capabilities: Sending An iso class Bar actor Foo be baz(x: Bar iso) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover iso Bar end f.baz(consume b) Main Foo f Bar b baz( ) x
  • 157. Reference Capabilities: Sending An iso class Bar actor Foo be baz(x: Bar iso) => // do something with x actor Main new create(env: Env) => let f = Foo let b = recover iso Bar end f.baz(consume b) Main Foo f Bar b x ● The Read Rule: If an actor can read an object then no other actor can modify that object ● The Write Rule: If an actor can modify an object then no other actor can read or modify it
  • 158. No More Data Races
  • 159. No More Data Races use “collections” actor Counter var _count: U64 = 0 be increment() => _count = _count + 1 be print(env: Env) => env.out.print(_count.string()) actor Incrementer new create(counter: Counter, main: Main) => for x in Range(0, 1_000_001) do counter.increment() end main.finished(this) actor Main let _finished_count = 0 let _counter: Counter = Counter let _env: Env new create(env: Env) => _env = env let inc1 = Incrementer(_counter, this) let inc2 = Incrementer(_counter, this) be finished() => _finished_count = _finished_count + 1 if _finished_count = 2 then _counter.print(env) end
  • 160. No More Data Races use “collections” actor Counter var _count: U64 = 0 be increment() => _count = _count + 1 be print(env: Env) => env.out.print(_count.string()) actor Incrementer new create(counter: Counter, main: Main) => for x in Range(0, 1_000_001) do counter.increment() end main.finished(this) actor Main let _finished_count = 0 let _counter: Counter = Counter let _env: Env new create(env: Env) => _env = env let inc1 = Incrementer(_counter, this) let inc2 = Incrementer(_counter, this) be finished() => _finished_count = _finished_count + 1 if _finished_count = 2 then _counter.print(env) end
  • 161. No More Data Races use “collections” actor Counter var _count: U64 = 0 be increment() => _count = _count + 1 be print(env: Env) => env.out.print(_count.string()) actor Incrementer new create(counter: Counter, main: Main) => for x in Range(0, 1_000_001) do counter.increment() end main.finished(this) actor Main let _finished_count = 0 let _counter: Counter = Counter let _env: Env new create(env: Env) => _env = env let inc1 = Incrementer(_counter, this) let inc2 = Incrementer(_counter, this) be finished() => _finished_count = _finished_count + 1 if _finished_count = 2 then _counter.print(env) end
  • 162. No More Data Races use “collections” actor Counter var _count: U64 = 0 be increment() => _count = _count + 1 be print(env: Env) => env.out.print(_count.string()) actor Incrementer new create(counter: Counter, main: Main) => for x in Range(0, 1_000_001) do counter.increment() end main.finished(this) actor Main let _finished_count = 0 let _counter: Counter = Counter let _env: Env new create(env: Env) => _env = env let inc1 = Incrementer(_counter, this) let inc2 = Incrementer(_counter, this) be finished() => _finished_count = _finished_count + 1 if _finished_count = 2 then _counter.print(env) end
  • 163. No More Data Races use “collections” actor Counter var _count: U64 = 0 be increment() => _count = _count + 1 be print(env: Env) => env.out.print(_count.string()) actor Incrementer new create(counter: Counter, main: Main) => for x in Range(0, 1_000_001) do counter.increment() end main.finished(this) actor Main let _finished_count = 0 let _counter: Counter = Counter let _env: Env new create(env: Env) => _env = env let inc1 = Incrementer(_counter, this) let inc2 = Incrementer(_counter, this) be finished() => _finished_count = _finished_count + 1 if _finished_count = 2 then _counter.print(env) end
  • 164. No More Data Races use “collections” actor Counter var _count: U64 = 0 be increment() => _count = _count + 1 be print(env: Env) => env.out.print(_count.string()) actor Incrementer new create(counter: Counter, main: Main) => for x in Range(0, 1_000_001) do counter.increment() end main.finished(this) actor Main let _finished_count = 0 let _counter: Counter = Counter let _env: Env new create(env: Env) => _env = env let inc1 = Incrementer(_counter, this) let inc2 = Incrementer(_counter, this) be finished() => _finished_count = _finished_count + 1 if _finished_count = 2 then _counter.print(env) end
  • 165. No More Data Races use “collections” actor Counter var _count: U64 = 0 be increment() => _count = _count + 1 be print(env: Env) => env.out.print(_count.string()) actor Incrementer new create(counter: Counter, main: Main) => for x in Range(0, 1_000_001) do counter.increment() end main.finished(this) actor Main let _finished_count = 0 let _counter: Counter = Counter let _env: Env new create(env: Env) => _env = env let inc1 = Incrementer(_counter, this) let inc2 = Incrementer(_counter, this) be finished() => _finished_count = _finished_count + 1 if _finished_count = 2 then _counter.print(env) end
  • 166. No More Data Races use “collections” actor Counter var _count: U64 = 0 be increment() => _count = _count + 1 be print(env: Env) => env.out.print(_count.string()) actor Incrementer new create(counter: Counter, main: Main) => for x in Range(0, 1_000_001) do counter.increment() end main.finished(this) actor Main let _finished_count = 0 let _counter: Counter = Counter let _env: Env new create(env: Env) => _env = env let inc1 = Incrementer(_counter, this) let inc2 = Incrementer(_counter, this) be finished() => _finished_count = _finished_count + 1 if _finished_count = 2 then _counter.print(env) end
  • 167. No More Data Races use “collections” actor Counter var _count: U64 = 0 be increment() => _count = _count + 1 be print(env: Env) => env.out.print(_count.string()) actor Incrementer new create(counter: Counter, main: Main) => for x in Range(0, 1_000_001) do counter.increment() end main.finished(this) actor Main let _finished_count = 0 let _counter: Counter = Counter let _env: Env new create(env: Env) => _env = env let inc1 = Incrementer(_counter, this) let inc2 = Incrementer(_counter, this) be finished() => _finished_count = _finished_count + 1 if _finished_count = 2 then _counter.print(env) end 2000000
  • 168. No More Data Races use “collections” actor Counter var _count: U64 = 0 be increment() => _count = _count + 1 be print(env: Env) => env.out.print(_count.string()) actor Incrementer new create(counter: Counter, main: Main) => for x in Range(0, 1_000_001) do counter.increment() end main.finished(this) actor Main let _finished_count = 0 let _counter: Counter = Counter let _env: Env new create(env: Env) => _env = env let inc1 = Incrementer(_counter, this) let inc2 = Incrementer(_counter, this) be finished() => _finished_count = _finished_count + 1 if _finished_count = 2 then _counter.print(env) end The Counter actor “protects” the _count data structure
  • 170. Sendence’s Experience With Pony It’s nice to catch errors a compile time rather than runtime
  • 171. Sendence’s Experience With Pony It’s nice to catch errors a compile time rather than runtime Pony is a young language (not even 1.0.0 yet)
  • 172. Sendence’s Experience With Pony It’s nice to catch errors a compile time rather than runtime Pony is a young language (not even 1.0.0 yet) ● limited documentation
  • 173. Sendence’s Experience With Pony It’s nice to catch errors a compile time rather than runtime Pony is a young language (not even 1.0.0 yet) ● limited documentation ● things change
  • 174. Sendence’s Experience With Pony It’s nice to catch errors a compile time rather than runtime Pony is a young language (not even 1.0.0 yet) ● limited documentation ● things change ● there are some sharp edges (compiler bugs, runtime bugs)
  • 175. Sendence’s Experience With Pony It’s nice to catch errors a compile time rather than runtime Pony is a young language (not even 1.0.0 yet) ● limited documentation ● things change ● there are some sharp edges (compiler bugs, runtime bugs) “America is all about speed. Hot, nasty, badass speed.” -- Eleanor Roosevelt PONY
  • 176. Learn More (because I left a lot out)
  • 177. Learn More User Mailing List ● https://pony.groups.io/g/user Website ● https://www.ponylang.org IRC ● freenode #ponylang
  • 179. Contribute Developer Mailing List ● https://pony.groups.io/g/dev Github ● Pony compiler → https://github.com/ponylang/ponyc ● RFCs → https://github.com/ponylang/rfcs