Files and Zones
A Polar file is a module, split into zones. Each zone holds one kind of declaration, so you always know where to look for something.
A file with several zones
module Todo
uses
Std.List
types
Task = { id: Int, title: String, done: Bool }
functions
open_tasks(tasks: List<Task>) -> List<Task> {
List.filter(tasks, function(t) { !t.done })
}
exports
open_tasks
Reading from the top:
-
usesimports modules.Std.Listis the standard list module. typesdeclares the shape of a task.-
functionsdefinesopen_tasks, which keeps only the tasks that aren't done. -
exportsmakesopen_tasksavailable to other modules.
Every zone
You only write the zones you need, but the ones you write must appear in this order, each at most once:
| Zone | Holds | Covered in |
|---|---|---|
uses |
Imported modules | Modules and Packages |
hosts |
Where the code runs, like Node or
Browser
|
Hosts |
traits |
Trait declarations | Traits |
types |
Records and variants | Records, Variants |
constants |
Named values with a type | Below |
effects |
Effect declarations | Effects |
externs |
Typed JavaScript functions | JavaScript Interop |
binds |
Effect implementations | Effects |
functions |
Functions | Functions |
impls |
Trait implementations | Traits |
exports |
Public names | Modules and Packages |
Put them out of order and the compiler tells you the right order:
error[POLAR0208]: the `traits` zone must come before `types`
--> traits.px:8:1
|
8 | traits
| ^^^^^^
9 | Area<a> {
10 | area(shape: a) -> Float
11 | }
| ^
|
= help: zones run `uses` -> `hosts` -> `traits` -> `types` -> `constants` -> `effects` -> `externs` -> `binds` -> `functions` -> `impls` -> `exports`, each at most once
Note: Packages can add zones of their
own, such as routes or views. See
Zone Plugins.
Constants
The constants zone holds values that never change. Each
one has a name, a type and a value:
constants
pi: Float = 3.141592653589793
greeting: String = "hello"
Comments
// starts a comment that runs to the end of the line.
/// starts a doc comment, which describes the
declaration below it:
functions
/// Adds two numbers.
add(a: Int, b: Int) -> Int {
// no overflow checks here
a + b
}
Now that we know where things go, let's look at what goes inside a function: values and expressions.