Developing concurrent programs with Pony

Subtyping

Listing 5 shows yet a further incompatibility in capabilities: The history declaration stipulates box (line 3), whereas in line 10, res attempts to insert an iso reference using push().

Of course consume deletes res; however, without the capability references, you could not write a meaningful program in Pony. Figure 5 shows the possible replacements that work in the direction of the arrow. For example, an iso can replace any other capability, but trn can only be used for val or ref, because trn permits additional read references of the box capability, which would contradict the exclusive character of iso. However, val can be replaced by trn after a consume removes the last writing reference of trn type.

Figure 5: Reference capabilities can be replaced transparently in the direction of the arrow. The subtype is to the left of the arrow in each case.

If you replace ref, you can allow other writing references without problems. The box and tag capabilities are not critical for val and ref because the latter cannot write. A blog post by developer John Mumm provides a more detailed explanation [9].

Blue Horses

The main.pony file shown in Listing 6 is the entry point in the example program; in the tradition of C, Pony uses main as the identifier for the program start point.

Like the familiar main() function in C or the main() method in Java, Pony defines an actor. In line 4, the actor's constructor accepts a reference to the executing environment of the program as an object of type Env. The next lines save the reference in the field with the name env in the Main instance.

Line 6 creates the actor of type Painter, as defined by Listing 5. The constructor uses this to receive simultaneously a reflexive reference to the Main actor. The for loop in lines 7 to 10 iterates over the field with the primitives [Amber, Blue, Crimson, Other] or, preferably, its iterator object.

On the basis of field values, line 8 generates an object of type Resource, as defined in Listing 3, and stores the reference in the run-time variable x. The expression recover Resource(x) end introduces a mechanism for arbitrarily setting a capability. In the present form, recover generates a reference of type iso.

Line 9 transfers the resource to the Painter actor. A further deletion process, courtesy of consume res, occurs before sending. As mentioned earlier, Painter finally calls the notify behavior in line 12. The message is a String type and ends up in the shell thanks to the env object.

Conclusions

Thanks to Pony, programmers can write what looks to be secure, high-performance code for concurrent programs. It is free of data races and deadlocks and follows the style of object-oriented languages. The actor model should not cause any trouble, but the difficulty of understanding capabilities could deter many users. The matter is even more complex when developers need to consider the resulting effects of a collection of several capabilities.

If the complexity does not deter you, you can improve the quality of your multithreaded programs; moreover, Pony can be docked on existing projects by integrating C code via the Foreign Function Interface (FFI).

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News