v0.2.0
A little magic in every line of code.
Pooka is a small, statically typed language for the BEAM. Immutable classes, interfaces, enums, pattern matching and actors, with errors you can hold in your hand, and good manners towards Erlang, Elixir and Gleam.
$
curl -fsSL https://pooka.run/install.sh | sh
On Windows? Follow the installation guide.
module main
import pooka/io
import pooka/list
class Lantern(name: String, lit: Bool)
glow(lantern: Lantern) -> String {
match lantern.lit {
True -> lantern.name + " is glowing"
False -> lantern.name + " waits in the dark"
}
}
main() {
[Lantern("Ada", True), Lantern("Bo", False)]
|> list.map(glow)
|> list.each(fn(line: String) {
let _ = io.println(line)
Nil
})
}
pooka run
Compiled 1 module in 0.41s
Running lantern.main
Ada is glowing
Bo waits in the dark
01 Quick start
From nothing to running in a minute.
01
Make a project
A pooka.toml, a src/main.pooka and a first test.
pooka new lantern cd lantern
02
Run it
Dependencies download, modules compile, main() runs.
pooka run pooka test
03
Bring friends
Any Hex package works: Pooka, Erlang, Elixir or Gleam.
pooka add arglet pooka add cowboy
02 A short walk
Read it once, remember it.
Every example below compiles and runs with Pooka 0.2.0.
module main
class Creature {
let name: String
new(name: String) {
self.name = name
}
greet() -> String {
"..."
}
}
class Owl is Creature {
new(name: String) {
super.new(name)
}
greet() -> String {
"hoo"
}
}
main() {
let owl: Creature = Owl("Ada")
echo owl.name + " says " + owl.greet()
}
pooka run
src/main.pooka:27
"Ada says hoo"module main
enum Weather {
Sunny,
Rainy,
Foggy
}
plan(weather: Weather) -> String {
match weather {
Weather.Sunny -> "walk to the harbour"
Weather.Rainy -> "write a parser"
Weather.Foggy -> "listen for the lighthouse"
}
}
main() {
echo plan(Weather.Rainy)
}
pooka run
src/main.pooka:18
"write a parser"module main
import pooka/int
import pooka/list
import pooka/string
main() {
[3, 1, 2]
|> list.sort
|> list.map(int.to_string)
|> string.join(", ")
|> echo
}
pooka run
src/main.pooka:12
"1, 2, 3"module main
import pooka/int
parse_cups(text: String) -> Result(Int, String) {
match int.parse(text) {
Ok(cups) if cups > 0 -> Ok(cups)
Ok(_) -> Error("at least one cup, please")
Error(_) -> Error("`" + text + "` is not a number")
}
}
brew(text: String) -> Result(String, String) {
let cups = parse_cups(text)?
Ok(int.to_string(cups) + " cups brewing")
}
main() {
echo brew("3")
echo brew("lots")
}
pooka run
src/main.pooka:19
Ok("3 cups brewing")
src/main.pooka:20
Error("`lots` is not a number")module main
actor Kettle {
var cups: Int = 0
be pour(count: Int) {
cups += count
}
poured() -> Int {
cups
}
}
main() {
let kettle = Kettle()
kettle.pour(2)
kettle.pour(1)
echo kettle.poured()
}
pooka run
src/main.pooka:19
3module main
external Math from erlang "math" {
sqrt(x: Float) -> Float
pi() -> Float
}
main() {
echo Math.sqrt(2.0)
echo Math.pi()
}
pooka run
src/main.pooka:10
1.4142135623730951
src/main.pooka:11
3.141592653589793error: non-exhaustive match
╭─ src/main.pooka:16:9
│
16 │ match weather {
│ ───┬───
│ ╰─ not every main.Weather value is handled
╰─
Every possible value of the matched type must be handled.
help: Handle `Weather.Foggy` or add a fallback branch.
03 Diagnostics
Errors that help.
When something is wrong, Pooka points at it, says why, and suggests what to do next.
- ✓LocatedFile, line and column, with the source right there.
- ✓ExplainedA sentence about the rule, not just the symptom.
- ✓ActionableA
help:line naming the missing case or the likely fix.
Light the lantern.
Install Pooka, make a project, and say hello to the BEAM. The tour takes an evening; the cookbook is there whenever you're hungry.