Getting to know Pony, an open-source, object-oriented, actor-model, capabilities-secure, high performance programming language.

At QCon London 2016 I saw a presentation on Pony and my interest was peaked enough to take a closer look at the language. In this article I will try to contrast Pony against my current favorite language, Go. (I will leave it to others to compare Pony with Erlang or Elixir)

Similarities with Go

Let’s start off by listing some of the characteristics shared between Go and Pony:

Ahead-of-time (AOT) compiled

Composition over inheritance

Garbage collected

Hard to Google

Inherent build system

Open Source

Statically typed

Structurally typed interfaces

Mostly insignificant whitespace

How is it different from Go?

Actor based concurrency (Mailboxes!)

Algebraic type expressions (Union types!)

Classes (composed of fields, constructors, and functions)

Default argument values

Erlang style Pattern Matching

Expressions with more than one infix operator must use parentheses to remove the ambiguity

Fully concurrent GC with no stop-the-world or sweep phase (Go GC is concurrent since 1.5)

Generics

Implicit return values (last expression)

let in addition to var

in addition to No null (but it has a None type)

(but it has a type) No deadlocks (since there are no locks at all)

No global variables (Go has package global variables)

Not possible to have data-races (ensured by the compiler)

User defined primitive types (like a class, but has no fields and there is only one instance)

Statements are expressions

Three kinds of type expressions: tuples, unions, and intersections

Trait system (similar to Java 8 interfaces that can have default implementations)

Type annotations to indicate capabilities (Rcaps)

Type aliases (enumerations, complex types)

~zero overhead when calling out to C

Installing Pony

If you are using OS X and have Homebrew installed, then you can install Pony like this:

$ brew install ponyc

The current version of ponyc as of this writing is 0.2.1.

Make sure you also get the pony-vim-syntax.

Hello, World!

The entry point of a Pony binary is the Main actor. The binary is named after the directory, just like how it works in Go.

ponyhello/main.pony

actor Main new create( env : Env ) => env . out . print( "Hello, World!" )

And as you probably know, the Go entry point is the main func.

gohello/main.go

package main import "fmt" func main () { fmt . Println ( "Hello, World!" ) }

Actors

The concurrency in Pony is based on Actors, just like in Erlang. Actors in Pony can, unlike classes, have behaviours (asynchronous methods)

Behaviours are asynchronous, but actors themselves are sequential. Actors will only execute a single behaviour at the same time.

Classes

A class in Pony can have multiple named constructors. Every constructor has to set every field in an object.

The underscore ( _ ) is used to make something private in Pony. (Exported identifiers in Go start with a upper case letter)

mascot/main.pony

actor Main let mascot : Mascot new create( env : Env ) => mascot = Mascot ( "Go gopher" ) env . out . print(mascot . message()) class Mascot let _name : String new create(name: String) => _name = name fun message(): String => "The " + _name + " is the best mascot!"

Learn more about Pony

Bonus: Linking to the shared library from the article Go and Ruby-FFI

Pony includes a really nice C FFI library and this is an example of how you can use it:

use "path:." use "lib:sum" use @add [ I64 ] ( a : I64 , b : I64 ) actor Main new create( env : Env ) => env . out . print( "4+8 = " + @add( 4 , 8 ) . string())