1. AKA
An aka create a symbol that is an alias for another
expression. Everything can be used to create an alias, not necessarily
a value, or a type. The keyword aka
was choosed to avoid
confusion with alias
, that has a completely different meaning in
Ymir.
The grammar of akas is presented in the following code block.
aka_decl := 'aka' Identifier (templates)? = expression (';')?
1.1. Aka as a value
Aka can be used as a single value enumeration. As for enumeration values, akas are constructed at each access, and are for that reason closer to enumeration, than to global variable. In addition, akas are only defined during compilation time, and are not defined inside the executable, library, etc. generated by the compiler, contrary to global variables.
An example of an aka is presented in the source code below. In that
example, the aka refers to the call of the foo
function, that is
called each time the aka is used.
import std::io
aka CallFoo = foo ()
def foo () -> i32 {
println ("Foo");
42
}
def main () {
println (CallFoo);
println (CallFoo);
}
Results:
Foo
42
Foo
42
Because akas are not global variable, they don't have an address, and are always immutable. They don't really have a type, and simply stick their content, at the location of the caller. However, like enumeration values, their context is the one of their declaration, not the context of the caller. For that reason by compiling the following example, the compiler returns an error.
import std::io
aka FOO = x // x is not defined in this context
def main () {
let x = 12; // this x is local, and not accessible from FOO
println (FOO); // does not work
}
Error:
Error : undefined type x
--> main.yr:(3,11)
3 ┃ aka FOO = x
╋ ^
1.2. Aka as a type
Akas do not always referes to values, but can also refer to type. The symbol access rules are the same as value akas.
import std::io
aka MyTuple = (i32, i32)
def foo (a : MyTuple) {
println ("x: ", a.0, ", y: ", a.1);
}
def main () {
let x = (1, 2);
foo (x);
}
Results:
x: 1, y: 2
Akas type are not real type, meaning that the definition of foo
in the previous example, is strictly equivalent to
def foo (a : (i32, i32)) {
println ("x: ", a.0, ", y: ", a.1);
}
1.3. Aka as symbols
Akas are not confined to type, and values. They can create symbols to refer to other symbols. For example modules, functions, structures, etc.
import std::io
aka IO = std::io
def println (a : i32) {
IO::println ("My println : ", a);
}
def main () {
IO::println (12);
println (12);
}
Results:
12
My println : 12
Contribution : enable aka on import, with the syntax : import
path aka name
. This is already possible, as we can see in the
previous example, but needs two lines.