Modules
A source file may start with a module declaration:
module my.hello_module
fun hello() {
print("hello");
}
type MyType {
// ...
}
If the file starts with a module declaration, all functions and types in the file are contained in this module.
So, for the above example, hello()
is actually my.hello_module.hello()
, and MyType
is my.hello_module.MyType
module block
With module blocks, we can declare multiple modules in one file
module my.hello_module {
fun hello() {
// ...
}
// ...
}
module my.other_module {
fun hello() { // we can have same names in different modules
}
// ...
}
And even with hierarchies to declare nested modules
module my {
module hello_module {
fun hello() {
// ...
}
module tree {
type tree {
// ...
}
}
}
}
Using a module
To use functions and types in a module, we need to import them.
The Venus standard libraries are contained in module std
import std.io // imports all symbols from module std.io
main {
println("Hello") // println is actually std.io.println(), after import, we can use the simple name instead of full name
std.io.println("hello") // full name is also OK.
}
If we put import
statement at the head of a scope, then we can use it in every place in the scope.
In the above example, we import std.io
at the head of the file, so it is seen throughout the file.
We can also put the import
statement in other places to give more control:
main {
import std.io // we only import std.io in `main`
println("Hello")
}
hello(string name) {
println(name) // ERROR! println is not imported!
}
Here std.io
is imported in main
, so using println
in hello()
will be a compiler error because hello()
is out of the scope of main
.
Selective imports
If we want to import only one symbol from a module:
import std.io.println
Here we import println
, and other symbols like print
are not seen.
If we want to import more than one symbols:
import std.io { println, File }
import std.io print, getchar // ignoring the braces is OK here
If we need an alias of the symbol imported, perhaps to avoid name conflict with another module, or we just want a shorter name we can use:
import std.io { println: prtln, File }
main {
prtln("Hello!") // prtln is an alias of std.io.println
}
Here println is aliased, but File stays the same.
Visibility
Symbols defined in a module are visible only if they are public:
import std.io
module my.hello {
public type hello {
saySomething() // calling functions in the same module is OK
println("hello")
}
saySomething {
println("hehehe...")
}
}
main {
import my.hello
hello("world!") // ok, because `hello` is declared public
saySomething() // ERORR! `saySomething()` is not visible
}