A brief dive into the Pony programming language
Tags: programming, languages, actormodel
Published: 2017-11-02 20:36:20

---
title: "A brief dive into the Pony programming language"
published: true
tags: programming, languages, actor-model
canonical_url: https://monades.roperzh.com/pony-programming-language/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ly0gulhw6cwen3ioko73.jpg
---

_This post was originally published on [monades.roperzh.com](https://monades.roperzh.com/pony-programming-language/?cm=devto)_

[Pony][pony-website] 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.

## Compiled

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.

```bash
$ cd myprogram
$ ponyc
$ ./myprogram
```

## Statically typed

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`.

```scala
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.

```scala
let hello = Hello("Seneca")
```

## Object oriented

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][traits-and-interfaces].

```scala
class Book
  // Fields of a given class are defined
  // like this.
  // - `var` fields can be asigned 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
```

## Actor Model

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][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 syncronously, instead, it will be executed at some indeterminate time in the future.

```scala
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)
```

### Communicating with Actors

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][kevin-hoffman-promises-blogpost] by Kevin Hoffman on the subject.

```scala
// 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 fullfilled
// using a partial application of `env.out.print`
promise.next[None](env.out~print())
```

## PonyTest

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.

```scala
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)
```

## Interesting facts

- 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`

## Stats

- **~5 years** of life, first commit at Nov 9, 2012
- **4,549** commits
- **46** releases
- **104** contributors
- **2,672** GitHub stars
- **76** questions tagged with `pony` in StackOverflow

<br>

_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._

## Resources

- [Website][pony-website]
- [Tutorial][pony-tutorial]
- [Common Patterns Cookbook][common-patterns-cookbook]
- [Examples][pony-examples]

[pony-website]: https://www.ponylang.org/
[pony-tutorial]: https://tutorial.ponylang.org/
[common-patterns-cookbook]: https://patterns.ponylang.org/
[pony-examples]: https://github.com/ponylang/ponyc/tree/master/examples
[traits-and-interfaces]: https://tutorial.ponylang.org/types/traits-and-interfaces.html
[actor-model]: https://monades.roperzh.com/get-to-know-the-actor-model/
[kevin-hoffman-promises-blogpost]: https://medium.com/@KevinHoffman/the-promise-of-ponys-future-44040a0b64ff