A brief dive into the Pony programming language November 2nd, 2017

Pony is an emerging programming language which is described by its authors as “an open-source, object-oriented, actor-model, capabilities-secure, high-performance programming language.”

Wording aside, this article focuses on the most interesting aspects of the language itself and how the code looks like.

Pony inhabits in the reigns of compiled languages, when executing the ponyc command (which is part of the Pony installation) the compiler creates an executable with the same name of the current folder.

$ cd myprogram $ ponyc $ ./myprogram

A lot of the guarantees that Pony offers (no exceptions at runtime, secure capabilities and more) are backed up by its type system. If you miss a type or assign a value to a variable of a different type, the compiler complains and stops the compilation.

The syntax to denote a type is variable: Type .

class Hello // name is a variable of type String let name : String // age is a variable of type U64 let age : U64 // the argument name' is a variable of type string new create ( name ' : String ) => name = name '

However, in certain scenarios, types are inferred by the compiler. Here, for example, the type of the hello variable can be safely omitted.

let hello = Hello ( "Seneca" )

Pony is object-oriented and exposes it with classes. A class is declared with the keyword class , and can have:

One or many constructors differentiated by name

Fields

Functions

Unlike many other OOP languages, Pony doesn’t have the concept of inheritance, instead it embraces traits and interfaces.

class Book // Fields of a given class are defined // like this. // - `var` fields can be assigned multiple times // - `let` fields can only be assigned once in the constructor. // - fields starting with underscore are private let author : String var _editions : U32 new create ( author ' : String , editions ' : U32 ) => author = author ' _editions = editions ' // A class can have functions fun get_author () : String => author fun get_editions () : U32 => _editions // To set values, is necessary to mark // the function as `ref` fun ref set_editions ( to : U32 ) => _editions = to

Pony embraces the Actor Model and supports it out of the box. If you haven’t heard of it, and you’re interested, feel free to check out Get to Know the Actor Model.

In the Pony world, actors are similar to classes, with the only difference that they are asynchronous entities. Instead of functions an actor has behaviors; when called, the body of a behavior is not executed synchronously, instead, it will be executed at some indeterminate time in the future.

use "promises" actor Writer // As with classes, you can define fields let name : String // And constructors too! new create ( name ' : String ) => name = name ' // Instead of functions, an Actor has behaviors be get_name ( promise : Promise [ String ]) => promise ( name )

Hence the asynchronous nature of actors, Pony also comes with primitives to enable asynchronous communication through Promise s. A Promise represents a value that will be available at a later time. Promise s are either fulfilled with a value or rejected. If you’re interested in the details of Pony promises, there’s an excellent blog post by Kevin Hoffman on the subject.

// Create a new Actor let writer = Writer ( "Italo Calvino" ) // Create a new promise let promise = Promise [ String ] // Invoke the Actor behavior, providing a // promise to be fulfilled writer . get_name ( promise ) // Print the value of the promise when fulfilled // using a partial application of `env.out.print` promise . next [ None ]( env . out ~ print ())

Pony comes with the PonyTest package which provides a simple unit testing framework: each unit test is a class, with a single test function, and by default, all tests run concurrently.

use "ponytest" actor Main is TestList new create ( env : Env ) => PonyTest ( env , this ) fun tag tests ( test : PonyTest ) => test ( _TestAdd ) class iso _TestAdd is UnitTest fun name () : String => "addition" fun apply ( h : TestHelper ) => h . assert_eq [ U32 ]( 4 , 2 + 2 )

You integrate Pony with C through the Foreign Function Interface (FFI)

Division by zero is allowed, and results in zero

a = b is an expression that returns the old value of a

~5 years of life, first commit at Nov 9, 2012

of life, first commit at Nov 9, 2012 4,549 commits

commits 46 releases

releases 104 contributors

contributors 2,672 GitHub stars

GitHub stars 76 questions tagged with pony in StackOverflow





note: this numbers date of 10/31/2017, they become more and more invalid as time goes on; moreover, they don’t represent anything significant and are included only for fun.