This chapter covers the various expressions that make up Pony. From variables to control structures and more.
What do we want?
Where do we want them?
In our Pony programs!
Say no more
Every programming language has literals to encode values of certain types, and so does Pony.
In Pony you can express booleans, numeric types, characters, strings and arrays as literals.
Bool Literals There is true, there is false. That’s it.
Numeric Literals Numeric literals can be used to encode any signed or unsigned integer or floating point number.
Like most other programming languages Pony allows you to store data in variables. There are a few different kinds of variables which have different lifetimes and are used for slightly different purposes.
Local variables Local variables in Pony work very much as they do in other languages, allowing you to store temporary values while you perform calculations. Local variables live within a chunk of code (they are local to that chunk) and are created every time that code chunk executes and disposed of when it completes.
Infix Operators Infix operators take two operands and are written between those operands. Arithmetic and comparison operators are the most common:
1 + 2 a < b Pony has pretty much the same set of infix operators as other languages.
Operator aliasing Most infix operators in Pony are actually aliases for functions. The left operand is the receiver the function is called on and the right operand is passed as an argument.
Arithmetic is about the stuff you learn to do with numbers in primary school: Addition, Subtraction, Multiplication, Division and so on. Piece of cake. We all know that stuff. We nonetheless want to spend a whole section on this topic, because when it comes to computers the devil is in the details.
As introduced in Primitives numeric types in Pony are represented as a special kind of primitive that maps to machine words.
To do real work in a program you have to be able to make decisions, iterate through collections of items and perform actions repeatedly. For this, you need control structures. Pony has control structures that will be familiar to programmers who have used most languages, such as if, while and for, but in Pony, they work slightly differently.
Conditionals The simplest control structure is the good old if. It allows you to perform some action only when a condition is true.
All Pony code that actually does something, rather than defining types etc, appears in named blocks which are referred to as methods. There are three kinds of methods: functions, constructors, and behaviours. All methods are attached to type definitions (e.g. classes) - there are no global functions.
Behaviours are used for handling asynchronous messages sent to actors, which we’ve seen in the “Types” chapter when we talked about actors.
Pony doesn’t feature exceptions as you might be familiar with them from languages like Python, Java, C++ et al. It does, however, provide a simple partial function mechanism to aid in error handling. Partial functions and the error keyword used to raise them look similar to exceptions in other languages but have some important semantic differences. Let’s take a look at how you work with Pony’s error and then how it differs from the exceptions you might be used to.
Pony features two forms of equality: by structure and by identity.
Identity equality Identity equality checks in Pony are done via the is keyword. is verifies that the two items are the same.
if None is None then // TRUE! // There is only 1 None so the identity is the same end let a = Foo("hi") let b = Foo("hi") if a is b then // NOPE. THIS IS FALSE end let c = a if a is c then // YUP!
Pony allows you to omit certain small details from your code and will put them back in for you. This is done to help make your code less cluttered and more readable. Using sugar is entirely optional, you can always write out the full version if you prefer.
Apply Many Pony classes have a function called apply which performs whatever action is most common for that type. Pony allows you to omit the word apply and just attempt to do a call directly on the object.
But Pony is statically typed, so an object literal also creates an anonymous type that the object literal fulfills. This is similar to anonymous classes in Java and C#.
Partial application lets us supply some of the arguments to a constructor, function, or behaviour, and get back something that lets us supply the rest of the arguments later.
A simple case A simple case is to create a “callback” function. For example:
class Foo var _f: F64 = 0 fun ref addmul(add: F64, mul: F64): F64 => _f = (_f + add) * mul class Bar fun apply() => let foo: Foo = Foo let f = foo~addmul(3) f(4) This is a bit of a silly example, but hopefully, the idea is clear.