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.