This post walks through the Pony "hello world" program.
First, the program in all its glory.
actor Main
new create(env: Env) =>
env.out.print("Hello, World")
Pony's concurrency model is based on actors. In essence, an actor is
an object that guarantees that all of its methods are executed
sequentially in a single thread. You don't need to fully understand
this in order to understand the "Hello World" program, though. Just
note that every Pony program requires there to be one actor named
Main
in order to work properly.
The new
keyword signifies that the program is defining a
constructor. In this case, the constructor will return a new instance
of the Main
actor. Because this is the Main
actor, the constructor
must be named create
. However, in general, except for a few other
constraints*, the name of the constructor can be whatever the
programmer wishes.
This constructor also requires there to be a single argument with the
type Env
. Since this is a constructor, the return type is implicitly
the type of the actor that defines it. In this case, that is the type
Main
. Finally, the =>
denotes that the body of the constructor
begins.
For this program, the body of the constructor is a single line of code
that prints the text "Hello, World" to standard out. Pony does not
have any global variables, thus anything about the program's
environment that's typically global is provided by the Env
instance
passed into the constructor.
The Env
instance, referenced by the env
variable, has a field
named out
that references standard out, and is accessed by dot
notation. Lets not concern ourselves with the type of the out
field,
but note that it has a method called print
that is accepting a
String
literal. Methods are also accessed by dot notation. The
difference between field and method access is that methods require
parenthesis after the name. The print
method will then print the
provided string to standard out followed by a new line character.
The Pony compiler will create an executable that instantiates and
instance of an actor of type Main
using the create
constructor.
This assumes you have the Pony compiler ponyc
installed and that
you're currently in a directory named hello
.
$ pwd
/Users/jeremy/src/pony/hello
$ ls
main.pony
$ cat main.pony
actor Main
new create(env: Env) =>
env.out.print("Hello, World")
hello:$ ponyc
Building . -> /Users/jeremy/src/pony/hello
Building builtin -> /usr/local/Cellar/ponyc/0.2.1/packages/builtin
Generating
Optimising
Writing ./hello.o
Linking ./hello
$ ls
hello hello.dSYM main.pony
$ ./hello
Hello, World
Q: Is whitespace significant like in Python?
A: No. The indentation in this program is by convention.
Q: Why doesn't the constructor body need an "end" token?
A: Every constructor definition begins with the new
keyword. If
another constructor followed the create
constructor, the compiler
would see another new
and start defining another constructor. (For
methods the keyword is fun
, and the keywords for fields are let
and var
.)
Q: Why is the executable named hello
?
A: By default ponyc
uses the name of the directory it is invoked in.