The summit
You have installed a compiler, written a script, used a prompt, learned the values and the control flow, the errors and the optionals, the structs, enums and traits, the ownership rules, the collections, built a calculator and a to-do list, parsed binary data, computed at compile time, written tests, read effects, run threads, served HTTP, drawn a window, made a package, shipped a library to three other languages, and trained a neural network. That is the language. There is no chapter on advanced features that the rest of us were keeping from you.
What to read now#
- The language reference: every construct, one paragraph each. It is the page to keep open while writing.
- The standard library: every module and function, from the doc comments in
std/. - The specification: what the language promises, in the words the test suite is written against. Section 5 (ownership), 8 (effects) and 12 (what undefined behaviour is and is not) are the ones that repay a careful read.
- How Nexium works: the compiler stage by stage, for when you want to change it.
- Stability and platforms: what a version number means, which targets are tested.
What is coming#
The roadmap is public and specific. Since 1.0 the language has grown the ergonomics its compiler wanted while being written in itself (1.1), memory safety without a garbage collector, the view rules (1.2), a toolchain grown up: incremental builds, a semantic language server, nx bench, sanitizers (1.3), a standard library people stop supplementing (1.4), and its platforms: WebAssembly, 32-bit and ARM (1.5). The next themes:
- 1.6, the runtime that release builds deserve: fewer reference-count updates and bounds checks, faster maps, strings and parallel loops, each change measured against C on the numbers page.
- 1.7, the seam both ways: what chapter 20 shipped to Python and Rust grows to NumPy, exceptions and handles, error enums and
no_std, more languages out, and Python and Rust called from Nexium. - 1.8, nexium-gui grown up on Linux and macOS as well, a web front end made in Nexium, and the apps built on them.
- 2.0, the first breaking changes since 1.0, announced by a release that deprecates them two minors ahead.
Each release has a name from the mountain the project has been climbing, and the names document explains the scheme; this book is a topo because the releases are a route.
Joining in#
The repository is github.com/Londopy/nexium. Contributing says how a change gets in: an example with recorded output or a compile-fail case, a changelog line, a language change needs the constraint it serves, and the contributor license agreement signed by a comment on the pull request. Bugs go in the tracker; open ones the maintainers know about are listed in known issues, and security reports have their own path.
The compiler is written in the language this book teaches, and its test harness and fuzzer are too. If you want to know how a feature really works, self/check.nx and the check_*.nx modules beside it have the answer, and after these chapters you can read them.
Thanks for climbing.
Exercises#
The compiler grades these: nx topo 23 writes them into a directory, nx topo check runs them. Or do them here: the code is editable, Run runs it with the compiler in the page (it loads on the first run and never sends your code anywhere), Check grades it as nx topo check would, and Reset puts the exercise back. Ctrl+Enter runs.
write_highestwrite it
The last pitch uses the whole route. Fill in highest so the tests pass: the name of the
highest peak in lines like "Annapurna 8091", skipping blank lines, null when there is no
peak at all, and failing with BadLine on a line that is not a name and a height.
error Peaks { BadLine }
fn highest(text: []u8) -> Peaks!?[]u8 {
???
}
fn main() {
let list = "Annapurna 8091\nEverest 8849\n\nK2 8611\n"
let top = highest(list) catch { null }
println("{}", .{top orelse "none"})
}
test "the highest of three" { expect_eq((try highest("Annapurna 8091\nEverest 8849\nK2 8611")) orelse "", "Everest") }
test "blank lines are skipped" { expect_eq((try highest("\nCho Oyu 8188\n\n")) orelse "", "Cho Oyu") }
test "no peaks at all" { expect(try highest("\n \n") == null) }
test "a height that is not a number" {
_ = highest("Everest high") catch |e| { expect(e == error.BadLine); return }
expect(false)
}
test "a name without a height" {
_ = highest("Everest") catch |e| { expect(e == error.BadLine); return }
expect(false)
}
The recorded output
Everest
Hints
text.lines()andline.trim()take the text apart (chapters 3 and 9); the height is- the last word, and a name may have a space in it ("Cho Oyu 8188")
- an optional holds the best so far; it is
nullbefore the first peak (chapter 6) parse_intfails on a height that is not a number, and that failure is aBadLinetoo
Solution
error Peaks { BadLine }
fn highest(text: []u8) -> Peaks!?[]u8 {
var best: ?[]u8 = null
var best_h: u32 = 0
for raw in text.lines() {
let line = raw.trim()
if line.len == 0 { continue }
// the height is the last word; everything before it is the name
var cut = line.len
while cut > 0 and line[cut - 1] != ' ' { cut -= 1 }
if cut == 0 { return error.BadLine }
let h = line[cut..line.len].parse_int(u32) catch { return error.BadLine }
if best == null or h > best_h {
best = line[0..cut - 1].trim()
best_h = h
}
}
return best
}
fn main() {
let list = "Annapurna 8091\nEverest 8849\n\nK2 8611\n"
let top = highest(list) catch { null }
println("{}", .{top orelse "none"})
}
test "the highest of three" { expect_eq((try highest("Annapurna 8091\nEverest 8849\nK2 8611")) orelse "", "Everest") }
test "blank lines are skipped" { expect_eq((try highest("\nCho Oyu 8188\n\n")) orelse "", "Cho Oyu") }
test "no peaks at all" { expect(try highest("\n \n") == null) }
test "a height that is not a number" {
_ = highest("Everest high") catch |e| { expect(e == error.BadLine); return }
expect(false)
}
test "a name without a height" {
_ = highest("Everest") catch |e| { expect(e == error.BadLine); return }
expect(false)
}