Add methods

This commit is contained in:
Gender Demon 2021-02-01 11:37:13 +00:00
parent b3cb1d9e65
commit 0247b30479
1 changed files with 108 additions and 0 deletions

108
methods/main.pony Normal file
View File

@ -0,0 +1,108 @@
use "collections"
actor Main
new create(env: Env) =>
let list_of_numbers = List[U32].from([1; 2; 3; 4])
let is_odd = {(n: U32): Bool => (n % 2) == 1}
for odd_number in list_of_numbers.filter(is_odd).values() do
env.out.print(odd_number.string())
end
class C
// This function returns the value of the last expression
// in the function (x + y)
fun add(x: U32, y: U32): U32 =>
x + y
// This function is pointless; the return value is ignored
// Why? Because *no return type has been specified*.
// We have to specify a return type if we want functions
// to return anything
fun nop() =>
add(1, 2)
// Function notes
// Parameters cannot be assigned to within functions (they are effectively
// declared `let`)
// The whole function body itself is an expression, and the returned value
// is the value of that expression (which happens to be equal to the expression
// in the last line of the function)
// You can exit a function early using `return`; if the function has a return type
// then `return` must return the correct type, otherwise `return` should have no
// argument
// Constructors
// Pony constructors are different because you can name them, so you can have as many
// as you like
// By convention, the main constructor for each type (if the type *has* a main constructor)
// is called `create`
class Foo
var _x: U32
new create() =>
_x = 0
new from_int(x: U32) =>
_x = x
// You can exit a constructor early by using the `return` command. But keep in mind that
// all the fields on the object must have been assigned to for this to work (the constructor
// must always assign all an object's fields)
// You can access fields and methods from inside a class like this
class Bar
fun hello(name: String): String =>
"hello " + name
fun f() =>
let a = hello("Fred")
// Constructors are normally called "on a" type, like this
class Baz
fun honk() =>
let my_foo: Foo = Foo.create()
let other_foo: Foo = Foo.from_int(12)
// Constructors can also be called on an expression, like this
fun hank() =>
let my_foo: Foo = Foo.create()
let other_foo: Foo = my_foo.from_int(4)
// You can also reuse a variable name from a declaration like this
// (how does this work?)
var another_foo: Foo = another_foo.create()
// Functions are always called "on an" object. If the object is omitted then the current
// class is used.
class Coord
var _x: U32
var _y: U32
new create(x: U32 = 0, y: U32 = 0) =>
_x = x
_y = y
class Doer
fun f() =>
var a: Coord = Coord.create(3, 4)
// Notice you can give the arguments *out of order* using
// named arguments with `where`
var b: Coord = Coord.create(where y = 4, x = 3)
// And we can combine named and positional arguments, so long as positional
// arguments are the first ones in the call
var c: Coord = Coord.create(12 where y = 0)
// Method chaining
// Method chaining allows you to chain calls on an object without requiring the method
// to return its receiver
primitive Printer
fun print_two_strings(out: StdStream, s1: String, s2: String) =>
out.>print(s1).>print(s2)
// The above is equivalent to what follows
out.print(s1)
out.print(s2)
out
// The purpose of this "method chaining" is to allow you to
// chain calls on a method but ignore intermediary return values
// You can change the final .> to just . if you want to return the
// value from the final call