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#

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:

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.

write_highest.nx
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() and line.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 null before the first peak (chapter 6)
  • parse_int fails on a height that is not a number, and that failure is a BadLine too
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)
}