#init

#init allows you to define procedures that run before the main in your program. This allows you to do simple set ups and initialization before main is reached.

#init must be followed by a compile-time known procedure with the type signature, () -> void.

#init () { println("In #init procedure!"); } main :: () { println("In main!"); } // Output: // In #init procedure! // In main!

You are guaranteed that the runtime has been fully initialized before any #init procedure is invoked. This way, you know that printing and heap allocations will work from #init procedures.

Ordering with #after

The order of #init procedure is undefined and unstable if you change your program. However, by using the #after directive, you can specify a dependency of an #init procedure that is guaranteed to be executed before the procedure in question.

global_map: Map(str, i32); // Bind the #init statement to a symbol. prepare_map :: #init () { global_map = make(Map(str, i32)); } populate_map :: #init #after prepare_map () { global_map->put("A", 1); global_map->put("B", 2); global_map->put("C", 3); }

In this example, prepare_map is guaranteed to be run before populate_map because of the #after directive on populate_map.

You can specify as many #after directives as you want on a single #init procedure.

#init #after A #after B #after C () { // ... }

In this example, the #init procedures A, B and C will be run before this #init procedure.