Heron version 0.9: Modules without Global Static Data
I've recently posted Heron version 0.9 . The major new feature with this version is the module system. I am quite happy with the new module system because it makes it possible to write code which offers the convenience of using (what look like) global or static variables but without all of the disadvantages.
Most programmers know that static or global data is bad, but lets face the truth, sometimes it is just easier to define globally accessible data, rather than creating complex dependency injection frameworks.
Let me illustrate the problem with a little anecdote:
I had this problem recently where I tried to write a VM in C++. I decide that it would save quite a number of lines of code if I assumed that my VM would never be instantiated more than once, so I went ahead and used global variables for the stack, heap, instruction counter, etc.
Everything went fine until I decided I wanted continuations. In simple terms, I wanted to be able to capture the entire state of the VM, start a new VM, and place the old VM state on the stack. This would have required a bunch of new code, and would have been extremely inelegant. If only I had written the VM to begin with as a class. I decided to put the project on hold, until I Heron was ready and I would start again from scratch.
This scenario in Heron would be end much differently. All code in Heron occurs in modules. You can define module level variables, which have both module scope and module extent. Module scope looks to the average programmer like global scope, except when you realize that modules have to be instantiated in Heron before you use them.
Lets compare to Python. In Python, when you import a module, its variables have module extent, but have global scope. When another module imports the same module, these variables are overwritten. For more information on this see this StackOverflow question.
In Heron everyone who imports a module has to instantiate it. If you want to share a single module instantiation between other modules you can pass the module instance explicitly to other modules via module constructor parameters or other means.
Some other changes from previous versions of Heron to this one:
- The entry point of a program is a module function named "Main()". Previously it was the constructor of a class named "Main".
- The compile-time entry point of a program is a module function named "Meta()". Previously it was the constructor of a class named "Meta".
- The script top-level construct has been removed. For now everything has to be explicitly a module.
- Modules names must match file names.
- Modules can be inherited
- Modules can contain member variables and member functions
- User type declarations are listed after the module declaration
- When using the installer ".heron" files are automatically associated with the HeronEngine.exe
- Fixed a problem with the command-line resolution of file paths