What happens by default
Ordinary code looks like implicit, with no mention of memory anywhere. Every value comes from the allocator the running task has selected, here the process heap, so no signature carries an allocator and no call site passes one.
explicit is the same four lines with that written down. allocator.Arena.new() makes an allocator you hold, use points those lines at it, and arena.deinit() gives the memory back. The output is identical; the second version says where the bytes came from and when they were released.
moon has no garbage collector, and implicit still has nothing to release. Nothing owns greeting or words, and an unowned value in a block that selected no arena lives until the process exits, which is fine for four lines and a problem in a loop. The rest of the chapter deals with that.
fn implicit() {
let greeting = "Hello " + "moon"
let words = greeting.split(" ")
println(words.len())
println(words[0])
}
fn explicit() {
let arena = allocator.Arena.new()
context.allocator.use(arena)
let greeting = "Hello " + "moon"
let words = greeting.split(" ")
println(words.len())
println(words[0])
arena.deinit()
}
fn main() {
implicit()
explicit()
}
Examples use the moon toolchain version shown beside each result.
Expected: 2 Hello 2 Hello