Imports
Functions and structs can be imported from other files with the import
keyword. Consider this directory layout:
main.hop
hello.hop
helpers
├ goodbye.hop
└ pairs
└ pair_defs.hop
hello.hop defines the say_hello and hello_again functions, goodbye.hop
defines the say_goodbye function and pair_defs.hop defines the IntPair and
BytePair structs:
struct IntPair {
a: int
b: int
}
struct BytePair {
a: byte
b: byte
}
Importing Functions
Let's say we want to call the say_hello, hello_again and say_goodbye
functions in main.hop. We can bring them into scope like this:
import hello::{say_hello hello_again}
import helpers::goodbye::{say_goodbye}
fn main {
say_hello
hello_again
say_goodbye
}
When chop encounters an import statement, it goes and parses the appropriate
file. For the first import, chop looks for a file called hello.hop in the
same directory as the current file (main.hop). It then parses it and bring the
say_hello and hello_again functions into scope. When chop sees the second
import, it looks for the file helpers/goodbye.hop and brings the say_goodbye
function into scope.
Importing Overloaded Functions
You can import multiple functions with the same name as long as their parameters
do not overlap. If two functions with the same name have overlaping signatures,
chop will emit an error message. Here is an example of overlaping imports:
import a::{overloaded}
import b::{overloaded}
chop emits this error message:
$ chop main.hop
import error: imported function 'overloaded' overlaps with a previous import
--> main.hop:2:12
|
2 | import b::{overloaded}
| ^^^^^^^^^^
note: 'overloaded' is imported here
--> main.hop:1:12
|
1 | import a::{overloaded}
| ^^^^^^^^^^
note: previously imported signature is [int] -> [int]
note: new signature is [int] -> [int]
Imported functions can also conflict with functions defined in the current file. For example, this code contains an overlapping import:
fn overloaded int -> int {}
import a::{overloaded}
chop emits the following message:
$ chop main.hop
import error: imported function conflicts with a previously defined function
--> main.hop:2:12
|
2 | import b::{overloaded}
| ^^^^^^^^^^
note: 'overloaded' is defined here
--> main.hop:1:4
|
1 | fn overloaded int -> int {}
| ^^^^^^^^^^
note: definition of 'overloaded' has signature [int] -> [int]
note: imported function 'overloaded' has signature [int] -> [int]
Importing Structs
Structs can be imported with the import and struct keywords. If we want
to import the IntPair and BytePair structs, we can do this:
import struct helpers::pairs::pair_defs::{IntPair BytePair}
fn consume_int_pair IntPair { ~ }
fn consume_byte_pair BytePair { ~ }
Note that the import struct statement only imports the struct name (for use
in function signatures). The struct constructor and member accessors must be
imported separately like any other function:
import struct helpers::pairs::pair_defs::{IntPair}
import helper::pairs::pair_defs::{IntPair}
fn consume_pair IntPair { ~ }
fn main {
1 2 IntPair
consume_pair
}
Importing Modules
Sometimes it's easier to import a whole module. You can do this by not including
curly braces in the import statement. Then you can refer to imported functions
and types with the :: qualified syntax:
import helpers::pairs::pair_defs
fn consume_pair pair_defs::IntPair { ~ }
fn main {
1 2 pair_defs::IntPair
consume_pair
}
Unlike other languages, you cannot qualify a name more than once. For example,
you cannot do this because the compiler does not understand the doubly qualified
name pairs::pair_defs::IntPair:
import helpers::pairs
fn consume_pair pairs::pair_defs::IntPair { ~ }
Standard Library Imports
Imports that begin with std:: get looked up in the Hop standard library. More
about the standard library can be found in the standard library chapter.