Namespaces & globals
Split code into namespaces, control visibility, and use globals and aliases.
On this page
Every directory under src is a namespace. Declarations in a namespace are reached through its name, and markers decide who else can see them.
Use a namespace#
use makes a namespace available in the current file. Standard library namespaces start with valk.:
use valk.fs
use valk.time as clock
fn main() {
let path = fs.Path.new("docs").add("notes.txt")
println(path) // docs/notes.txt
println(clock.unix_ms() > 0) // true
}
- The last part of the path is the name:
use valk.fsgivesfs. use x as namepicks another name.- A project's own namespaces are its directories, so
src/greetings/isuse greetings. See Projects & packages.
Visibility#
An unmarked declaration is available throughout its package. A marker in front of it changes that:
| Marker | Visible |
|---|---|
| none | in this package |
- |
in this source file only |
-+ |
in this namespace only |
+ |
everywhere, also to other packages |
~ |
read-only outside this source file (properties and globals) |
~+ |
read-only outside this namespace |
+ fn public_api() String { return helper() }
fn helper() String { return "package wide" }
- fn file_only() {}
+ class Config {
+ name: String // everyone can read and change it
~+ version: uint (1) // everyone reads, only this namespace writes
- secret: String ("") // only this file
}
- is private to the file, not to the class: other code in the same file can still use it. Operator methods such as $eq and hash that standard containers call need +.
Globals#
A global holds one value per thread. A shared global is one value for the whole program:
global requests: uint
global greeting: String ("hello")
shared started_at: uint (42)
fn count() {
requests++
}
fn main() {
count()
count()
println(requests) // 2
println(greeting) // hello
println(started_at) // 42
}
- A default goes in parentheses and runs before
main. Defaults may read other globals; they run in the right order. - Without a default a global starts at zero, so classes, strings and closures need a default.
- A
sharedglobal is read asatomic T; see Sharing data between threads for what you can change through it.
Aliases, types and constants#
use valk.fs
alias Path for fs.Path // another name for a declaration
type Check (fn(int)(bool)) // a name for a type expression
value PAGE_SIZE (16 * 4) // a compile-time constant
fn main() {
let dir: Path = "."
let positive: Check = fn(n: int) bool { return n > 0 }
println(positive(PAGE_SIZE)) // true
println(PAGE_SIZE) // 64
println(dir) // .
}
Add $global after a declaration to use its name in every namespace without a prefix, for example alias Path for fs.Path $global.
