Skip to content

Use Statement

To use a module in your code you need to have a use command. This tells the compiler to find the module you need and make the types defined in it available to you. Every Pony file that needs to know about a type from a module must have a use command for it.

Use commands are a similar concept to Python and Java “import”, C/C++ “#include” and C# “using” commands, but not exactly the same. They come at the beginning of Pony files and look like this:

use "collections"

This will find all of the publicly visible types defined in the collections package and add them to the type namespace of the file containing the use command. These types are then available to use within that file, just as if they were defined locally.

For example, the standard library contains the package time. This contains the following definition (among others):

primitive Time
  fun now(): (I64, I64)

To access the now function just add a use command:

use "time"

class Foo
  fun f() =>
    (var secs, var nsecs) = Time.now()

Use names

As we saw above the use command adds all the public types from a module into the namespace of the using file. This means that using a module may define type names that you want to use for your own types. Furthermore, if you use two modules within a file they may both define the same type name, causing a clash in your namespace. For example:

// In package A
class Foo

// In package B
class Foo

// In your code
use "packageA"
use "packageB"

class Bar
  var _x: Foo

The declarations of _x is an error because we don’t know which Foo is being referred to. Actually using ‘Foo’ is not even required, simply using both moduleA and moduleB is enough to cause an error here.

To avoid this problem the use command allows you to specify an alias. If you do this then only that alias is put into your namespace. The types from the used package can then be accessed using this alias as a qualifier. Our example now becomes:

// In package A
class Foo

// In package B
class Foo

// In your code
use a = "packageA"
use b = "packageB"

class Bar
  var _x: a.Foo  // The Foo from package A
  var _y: b.Foo  // The Foo from package B

If you prefer you can give an alias to only one of the modules. Foo will then still be added to your namespace referring to the unaliased module:

// In package A
class Foo

// In package B
class Foo

// In your code
use "packageA"
use b = "packageB"

class Bar
  var _x: Foo  // The Foo from package A
  var _y: b.Foo  // The Foo from package B

Can I just specify the full module path and forget about the use command, like I do in Java and C#? No, you can’t do that in Pony. You can’t refer to one module based on a use command for another module and you can’t use types from a module without a use command for that module. Every module that you want to use must have its own use command.

Are there limits on the names I can use for an alias? Use alias names have to start with a lower case letter. Other than that you can use whatever name you want, as long as you’re not using that name for any other purpose in your file.

Scheme indicators

The string we give to a use command is known as the specifier. This consists of a scheme indicator and a locator, separated by a colon. The scheme indicator tells the use command what we want it to do. The default scheme specifier for including a module is currently package. If no colon is found within the specifier string then the use command assumes you meant package.

The following two use commands are exactly equivalent:

use "foo"
use "package:foo"

If you are using a locator string that includes a colon, for example, an absolute path in Windows, then you have to include the package scheme specifier:

use "C:/foo/bar"  // Error, scheme "C" is unknown
use "package:C:/foo/bar"  // OK

To allow use commands to be portable across operating systems, and to avoid confusion with escape characters, ‘/’ should always be used as the path separator in use commands, even on Windows.