Pony and reference capability closure

What is Pony

Do you know the language Pony? Simply put, it is a "statically typed object-oriented language that can perform parallel and parallel processing using the Actor model". In addition, it is a language called ** capabilities-secure ** that has abundant functions to detect not only types but also errors related to concurrency at compile time. Among them, I would like to briefly introduce ** reference capability **, which is a rudimentary concept, through closures.

Counter using closure

A counter implementation that is often cited as an example of closures. I implemented it in several languages to make it easier to understand the power of Pony's reference capability.

It is assumed that the following results will be output for both languages.

1
2
3
4
5
6
7
8
9
10

JavaScript

const createCounter = () => {
    let count = 0;

    return () => {
        count += 1;
        return count;
    }
}

const counter = createCounter();

Array.from({length: 10}, () =>
    console.log(counter())
)

Java

import java.util.function.*;
import java.util.stream.IntStream;

public class Counter {
    public static void main(String ...args) {
        final Supplier<IntSupplier> createCounter = () -> {
            //Since count is final, the value is rewritten using an array.
            final Integer[] count = {0};

            return () -> {
                count[0]++;
                return count[0];
            };
        };

        IntSupplier counter = createCounter.get();
        IntStream.rangeClosed(1, 10).forEach(i -> {
            System.out.println(counter.getAsInt());
        });
    }
}

Scala

object Counter extends App {
  val createCounter = () => {
    var count = 0

    () => {
      count += 1
      count
    }
  }

  val counter = createCounter()

  (1 to 10).foreach { _ =>
    println(counter())
  }
}

The implementation in JavaScript and Scala is similar in concept. What is similar is that an anonymous function can take a free variable, become a closure, and rewrite the value of the free variable.

On the other hand, Java can only import variables (* 1) declared with `` `final``` as free variables, so it is necessary to import mutable objects such as arrays instead of primitive values and rewrite the reference destination. You can only change the value with. This is safe and correct behavior for closures, but it can be harsh in terms of convenience and readability.

Counter by Pony

So what approach does Pony take to solve the language problems listed above? Notice the variable `count``` that appears in the code. By default, Pony cannot rewrite the values of free variables taken from outside the lambda expression. In this respect, it behaves like Java. If you want to rewrite the value of a variable, add the ref``` keyword to your lambda expression. Doing so allows the lambda expression itself to rewrite the variables inside. Also, `` count remains 0 outside of the lambda expression updating `` `count. If you really want to update it, you need an approach such as putting it in an array like Java, but it seems that there are few such cases, so you can write very safe code.

use "collections"

actor Main
  new create(env:Env) =>
    let createCounter = {(): {ref(): U32} => 
      var count = U32(0)
      
      //By using the ref keyword, it is possible to rewrite the value of count.
      {ref()(count): U32 => 
          count = count + 1
          count
      }
    }
    
    let counter = createCounter()
    
    for i in Range[U32](0,10) do
      env.out.print(counter().string())
    end

refIf you compile with the keywords removed, you will get the following error. It's very easy to understand.

Error:
main.pony:9:17: cannot write to a field in a box function. If you are trying to change state in a function use fun ref
          count = count + 1

Summary

It's a very simple example, but did closures convey the power of ** capabilities-secure ** code? I think it is attractive to be able to write code safely by switching modes, rather than unifying whether rewriting is possible or impossible depending on the language specifications. This is just one part of Pony's ** capabilities-secure ** appeal. Let's get in touch with Pony's charm together!

Supplement

Recommended Posts

Pony and reference capability closure
Basic data type and reference type
Basic data types and reference types (Java)
Java reference mechanism (stack and heap)
[PHP] Inheritance, protected and reference patterns
Java pass by value and pass by reference
Difference between primitive type and reference type
About Java primitive types and reference types
Java basic data types and reference types