Initial commit

This commit is contained in:
Callum Renwick 2020-12-31 12:53:44 +00:00
commit b57a2e7afc
4 changed files with 128 additions and 0 deletions

18
actors/main.pony Normal file
View File

@ -0,0 +1,18 @@
actor Main
new create(env: Env) =>
call_me_later(env)
env.out.print("This is printed first")
be call_me_later(env: Env) =>
env.out.print("This is printed last")
actor Aardvark
let name: String
var _hunger_level: U64 = 0
new create(name': String) =>
name = name'
be eat(amount: U64) =>
_hunger_level = _hunger_level - amount.min(_hunger_level)

20
primitives/main.pony Normal file
View File

@ -0,0 +1,20 @@
actor Main
new create(env: Env) =>
let doorState : DoorState = ClosedDoor
let isDoorOpen : Bool = match doorState
| OpenedDoor => true
| ClosedDoor => false
end
env.out.print("Is door open? " + isDoorOpen.string())
env.out.print("2 + 3 = " + BasicMath.add(2,3).string())
primitive OpenedDoor
primitive ClosedDoor
type DoorState is (OpenedDoor | ClosedDoor)
primitive BasicMath
fun add(a: U64, b: U64): U64 =>
a + b
fun multiply(a: U64, b: U64): U64 =>
a * b

59
subtypes/main.pony Normal file
View File

@ -0,0 +1,59 @@
// There are two kinds of subtyping
// This is nominal subtyping
// This is a lot like what Java does with classes and interfaces
// First, define a trait
trait Named
// This is the default implementation of name()
fun name(): String => "Bob"
// Now, define a class that has that trait, using the `is` keyword
class Bob is Named
// The class Bob provides Named (or, more laconically, Bob is Named)
// If Bob doesn't provide a definition for name(), it will inherit the default
// implementation from Named
trait Bald
fun hair(): Bool => false
// A class can provide more than one trait
class Alice is (Named & Bald)
// All Funky classes are also Named, automatically
trait Funky is Named
fun funk_it(): I32 => 111
// This class is Funky and Named
class Charlie is Funky
// Doreen does not provide Named, even though it matches the interface.
// This is because traits are nominal: a class provides a trait only if
// it *says* it does.
class Doreen
fun name(): String => "Doreen"
// A concrete type is a member of a structural category if it has all the needed
// elements, no matter what it happens to be called.
interface HasName
fun name(): String
// All the classes above that implement name() or inherit an implementation (Bob,
// Alice, Charlie and Doreen) provide HasName. Even if the writer(s) of those
// classes did not intend it or are aware of it at all.
// Pony interfaces can have functions with default implementations, just like Pony
// traits. But a type will only be able to use those if they are declared as
// implementing the interface with the `is` keyword.
interface Excellent
fun nice(): String => "party time!"
class Edward is Excellent
let _priv: I32
new create(nothing: String) =>
_priv = 12
actor Main
new create(env: Env) =>
let ed = Edward("Pointless")
env.out.print(ed.nice())

31
type_aliases/main.pony Normal file
View File

@ -0,0 +1,31 @@
primitive Red
primitive Blue
primitive Green
// Let Colour be an alias for the union type (Red | Blue | Green)
type Colour is (Red | Blue | Green)
// ColourList is a constant representing the union type
primitive ColourList
fun apply(): Array[Colour] =>
[Red; Green; Blue]
for colour in ColourList().values() do
end
// Type aliases can also be used to give simpler names to complex types
interface HasName
fun name(): String
interface HasAge
fun age(): U32
interface HasFeelings
fun feeling(): String
// Let Person be an alias for the intersection of those three types
// This makes it easier to refer to
type Person is (HasName & HasAge & HasFeelings)
// You can do this with traits as well as interfaces.