Small how do I examples for Pony. These will eventually find another home. Until then, they live here.

Enum with values

  1. primitive Black fun apply(): U32 => 0xFF000000
  2. primitive Red fun apply(): U32 => 0xFFFF0000

Enum with values with namespace

  1. primitive Colours
  2. fun black(): U32 => 0xFF000000
  3. fun red(): U32 => 0xFFFF0000

Enum which can be iterated

  1. primitive Black
  2. primitive Blue
  3. primitive Red
  4. primitive Yellow
  5. type Colour is (Black | Blue | Red | Yellow)
  6. primitive ColourList
  7. fun tag apply(): Array[Colour] =>
  8. [Black; Blue; Red; Yellow]
  9. for colour in ColourList().values() do
  10. end

Read struct values from FFI

If you have a C struct which returns a struct with data like this

  1. typedef struct {
  2. uint8_t code;
  3. float x;
  4. float y;
  5. } EGLEvent;
  6. EGLEvent getEvent() {
  7. EGLEvent e = {1, ev.xconfigure.width, ev.xconfigure.height};
  8. return e;
  9. }

the you can destructure it and get the values using a tuple

  1. type EGLEvent is (U8, F32, F32)
  2. (var code, var x, var y) = @getEvent[EGLEvent]()

Get and pass pointers to FFI

  1. primitive _XDisplayHandle
  2. primitive _EGLDisplayHandle
  3. let x_dpy = @XOpenDisplay[Pointer[_XDisplayHandle]](U32(0))
  4. if x_dpy.is_null() then
  5. env.out.print("XOpenDisplay failed")
  6. end
  7. let e_dpy = @eglGetDisplay[Pointer[_EGLDisplayHandle]](x_dpy)
  8. if e_dpy.is_null() then
  9. env.out.print("eglGetDisplay failed")
  10. end

Pass an Array of values to FFI (TODO)

  1. primitive _EGLConfigHandle
  2. let a = Array[U16](8)
  3. a.push(0x3040)
  4. a.push(0x4)
  5. a.push(0x3033)
  6. a.push(0x4)
  7. a.push(0x3022)
  8. a.push(0x8)
  9. a.push(0x3023)
  10. a.push(0x8)
  11. a.push(0x3024)
  12. let config = Pointer[_EGLConfigHandle]
  13. if @eglChooseConfig[U32](e_dpy, a, config, U32(1), Pointer[U32]) == 0 then
  14. env.out.print("eglChooseConfig failed")
  15. end

How to access command line arguments

  1. actor Main
  2. new create(env: Env) =>
  3. // The no of arguments
  4. env.out.print(env.args.size().string())
  5. for value in env.args.values() do
  6. env.out.print(value)
  7. end
  8. // Access the arguments the first one will always be the application name
  9. try env.out.print(env.args(0)?) end

How to use cli to parse command line arguments

  1. use "cli"
  2. actor Main
  3. new create(env: Env) =>
  4. let command_spec =
  5. try
  6. CommandSpec.leaf(
  7. "pony-embed",
  8. "sample program",
  9. [ OptionSpec.string("output", "output filename", 'o') ],
  10. [ ArgSpec.string("input", "source of input" where default' = "-") ]
  11. )? .> add_help()?
  12. else
  13. env.exitcode(1)
  14. return
  15. end
  16. let command =
  17. match CommandParser(command_spec).parse(env.args, env.vars)
  18. | let c: Command => c
  19. | let ch: CommandHelp =>
  20. ch.print_help(env.out)
  21. env.exitcode(0)
  22. return
  23. | let se: SyntaxError =>
  24. env.err.print(se.string())
  25. env.exitcode(1)
  26. return
  27. end
  28. let input_source = command.arg("input").string()
  29. let output_filename = command.option("output").string()
  30. env.out.print("Loading data from " + input_source + ". Writing output to " + output_filename)
  31. // ...

How to write tests

Just create a test.pony file

  1. use "ponytest"
  2. actor Main is TestList
  3. new create(env: Env) => PonyTest(env, this)
  4. new make() => None
  5. fun tag tests(test: PonyTest) =>
  6. test(_TestAddition)
  7. class iso _TestAddition is UnitTest
  8. """
  9. Adding 2 numbers
  10. """
  11. fun name(): String => "u32/add"
  12. fun apply(h: TestHelper): TestResult =>
  13. h.expect_eq[U32](2 + 2, 4)

Some assertions you can make with the TestHelper are

  1. fun tag log(msg: String, verbose: Bool = false)
  2. be fail() =>
  3. be assert_failed(msg: String) =>
  4. fun tag assert_true(actual: Bool, msg: String = "") ?
  5. fun tag expect_true(actual: Bool, msg: String = ""): Bool
  6. fun tag assert_false(actual: Bool, msg: String = "") ?
  7. fun tag expect_false(actual: Bool, msg: String = ""): Bool
  8. fun tag assert_error(test: ITest, msg: String = "") ?
  9. fun tag expect_error(test: ITest box, msg: String = ""): Bool
  10. fun tag assert_is (expect: Any, actual: Any, msg: String = "") ?
  11. fun tag expect_is (expect: Any, actual: Any, msg: String = ""): Bool
  12. fun tag assert_eq[A: (Equatable[A] #read & Stringable)]
  13. (expect: A, actual: A, msg: String = "") ?
  14. fun tag expect_eq[A: (Equatable[A] #read & Stringable)]
  15. (expect: A, actual: A, msg: String = ""): Bool

Operator overloading (easy for copy and paste)

  1. fun add(other: A): A
  2. fun sub(other: A): A
  3. fun mul(other: A): A
  4. fun div(other: A): A
  5. fun rem(other: A): A
  6. fun mod(other: A): A
  7. fun eq(other: A): Bool
  8. fun ne(other: A): Bool
  9. fun lt(other: A): Bool
  10. fun le(other: A): Bool
  11. fun ge(other: A): Bool
  12. fun gt(other: A): Bool
  13. fun shl(other: A): A
  14. fun shr(other: A): A
  15. fun op_and(other:A): A
  16. fun op_or(other: A): A
  17. fun op_xor(othr: A): A

Create empty functions in a class

  1. class Test
  2. fun alpha() =>
  3. """
  4. """
  5. fun beta() =>
  6. """
  7. """

How to create Arrays with values

Single values can be separated by semicolon or newline.

  1. let dice: Array[U32] = [1; 2; 3
  2. 4
  3. 5
  4. 6
  5. ]

How to modify a lexically captured variable in a closure

  1. actor Main
  2. fun foo(n:U32): {ref(U32): U32} =>
  3. var s: Array[U32] = Array[U32].init(n, 1)
  4. {ref(i:U32)(s): U32 =>
  5. try
  6. s(0) = s(0) + i
  7. s(0)
  8. else
  9. 0
  10. end
  11. }
  12. new create(env:Env) =>
  13. var f = foo(5)
  14. env.out.print(f(10).string())
  15. env.out.print(f(20).string())