Your First Project
A single .px file is enough to try things out. Real
programs live in a project: a folder with a
polar.toml file and a src directory.
Create the project
polar init shop makes the folder,
polar.toml, src/main.px and a
.gitignore for you. To see what it writes, here is the
same thing by hand.
Let's make a project called shop that adds up prices.
Make this layout:
shop/
├── polar.toml
└── src/
├── main.px
└── money.px
polar.toml only needs a name:
[project]
name = "shop"
Polar fills in the rest with defaults. Here they are written out, in case you want to change them:
[project]
name = "shop"
src = "src" # where the .px files live
out = "dist" # where polar build writes
main = "src/main.px" # what polar run runs
Split code into modules
Each file is one module. Put the money helpers in
src/money.px:
module Money
types
Money = { cents: Int }
functions
cents(n: Int) -> Money {
{ cents: n }
}
add(a: Money, b: Money) -> Money {
{ cents: a.cents + b.cents }
}
format(m: Money) -> String {
let rest = m.cents % 100
let pad = if rest < 10 { "0" } else { "" }
"$#{m.cents / 100}.#{pad}#{rest}"
}
exports
cents
add
format
And use them from src/main.px:
module Main
uses
Money as M
Std.List
functions
main() {
let prices = [M.cents(250), M.cents(1999), M.cents(5)]
let total = List.fold(prices, M.cents(0), M.add)
Log.info("total: #{M.format(total)}")
}
exports
main
uses Money loads src/money.px. The
as M part is optional: it lets us write
M.add instead of Money.add. Only names
listed under exports can be used from other modules.
Run it
Inside a project, commands don't need a path:
$ cd shop
$ polar run
total: $22.54
Build it
polar build writes JavaScript into dist/:
$ polar build
built shop (2 files) into dist in 43ms
dist/
├── main.js main.js.map main.d.ts
├── money.js money.js.map money.d.ts
├── start.mjs
└── _polar/
Every module becomes a .js file with a source map and a
.d.ts type declaration. _polar/ holds the
small runtime. dist/ is self-contained, so you can copy
it anywhere and run it with Node:
$ node dist/start.mjs
total: $22.54
polar start does the same thing: it runs the existing
build without compiling again.
Use it from JavaScript
The built modules are ordinary ES modules, so JavaScript can import them directly:
// use.mjs
import { cents, add, format } from "./dist/money.js";
console.log(format(add(cents(1050), cents(99))));
$ node use.mjs
$11.49
TypeScript sees the types from money.d.ts:
export type Money = { cents: number };
export declare function cents(n: number): Money;
export declare function add(a: Money, b: Money): Money;
export declare function format(m: Money): string;
Keep it building
While you work, --watch rebuilds on every save:
$ polar check --watch # report errors only
$ polar build --watch # rebuild dist/ too
Next, let's set up your editor.