In Mita code is organized in packages, which serve multiple purposes:
- Divide the namespace: Mita programs have one global namespace per
.mita
file. Unlike Java for example, there are no means to qualify the name of an element. Packages are used to keep this namespace clean. Only things which are explicitly imported from other packages are visible in that namespace. See Importing Packages for more details. - Group code: packages are a formidable way to group code which conceptually belongs together. Where other languages have modules or classes, Mita uses packages.
- Hide information: in Mita visibility of functions, types and the likes is decided on a package level. There are only two levels of visibility: things are either visible outside a package or they are not. This is very similar to how NodeJS manages visibility (think
module.export
) or how Go does it (uppercase functions/structure members/types get exported). See Hiding Information for more details.
All Mita code belongs to a particular package. Thus, the first line in every .mita
file is the package
statement. The main application logic, for example, by convention is in the main
package:
package main;
...
Naming Conventions
Just now we have seen the first naming convention: the core application logic and system setup are in the main
package.
The platforms which we import – each Mita program needs to import a platform – are by convention found in the platforms
package.
The XDK110 platform for example is in the platforms.xdk110
package.
All in all you are free to name your packages however you like. The files which constitute your package content can be located wherever in the project. However, it is a good idea to replicate the logical package structure in folders. For example:
algorithm/
|- api.mita package algorithm
|- statistics.mita package algorithm.statistics
\- structures.mita package algorithm.structures
main.mita package main
Notice how we use a dot .
to indicate a sub-package relationship.
This is merely a convention and has no influence on visibility or any other implication.
Importing Packages
Packages divide the namespace, which is the space in which the names of functions and types have to be unique. Within a package all type names and functions (save for polymorphism) have to be unique. When we import a package, we import all names from that namespace into our local program. Consider the following example:
// file: mypackage.mita
package mypackage;
...
export fn answerTheQuestion() {
return 42;
}
// file: application.mita
package main;
import mypackage;
every XDK110.startup {
println(`The answer: ${answerTheQuestion()}`);
}
If it were not for the import mypackage
statement, the answerTheQuestion
function would not be visible in application.mita
.
To import a package use the import
statement. We have seen those in previous examples when we imported the platform, which is mandatory. Thus, every Mita program file must have at least one import: the platform import.
For example:
package main;
import platforms.xdk110;
...
You can shadow imported names within the current file. If in the example above application.mita
defined its own answerTheQuestion()
function, all code within application.mita
would refer to that one instead of the imported function.
Hiding Information (Visibility)
By default nothing is visible outside a package, nothing is exported to the outside world. This way, if you want to make things available outside the package, that has to be a conscious decision. To do so, mark what you want to export with the export
keyword. For example:
package utility;
import platforms.xdk110;
fn saturate(config : PidController) {
...
}
export fn control(config : PidController, input : int32) : int32 {
...
saturate(config);
...
}
In this example, the saturate
function is not visible outside the utility
package, but the control
function is because it is marked with the export
keyword.
This allows you to hide functions and types which are not meant for consumption outside of package and thus to provide a well defined API.
The generated C code will respect your export choices and mark non-exported objects as static
which is “C speak” for visible only within the same file.