The need for more structured code support has arisen with the addition of bigger and more sophisticated bindings like GTK one or the (soon to be released) work on alpha version of Red compiler (which emits Red/System code). So, v0.2.6 introduces namespaces support using a very simple, but efficient model.
For example, to encapsulate some variables and functions in a local context:
b: 1 a: context [ b: 2 inc: func [i [integer!] return: [integer!]][ i + b ] ] a/inc 5 ;-- will return 7
Local variables take precedence other global ones with same name. This simple rule also applies to nested contexts, the nearest one has priority, e.g.:
a: context [ b: 123 c: context [ #enum colors! [red green blue] b: "hello" foo: func [][print-line b] ] print-line b ;-- will output 123 c/foo ;-- will output hello ] print-line a/b ;-- will output 123 a/c/foo ;-- will output hello print-line a/c/b/2 ;-- will output e print-line a/c/blue ;-- will output 2
As you can see from this example, enumerations can also be defined locally to a context, but not only. Aliases and imported functions can also be defined locally too! With that powerful new feature, you can now modularize your Red/System programs simply and efficiently.
See the namespaces documentation for more features and info.
In this release you will also find several bugfixes, mainly for floats support. Thanks to Rebolek for his aggressive floats testing. ;-)
Enjoy!
Here is a quick update on Red/System progress.
Specifications Draft
Draft has gone through several revisions. Several decisions mainly regarding pointers handling have been taken with simplification and disambiguation as main goals:
A couple of things to keep in mind about Red/System design:
Implementation Progress
Several items from the todo-list have been implemented in the last week, the most notable ones being:
Among other changes:
An interesting side note on how implementation can influence back the design:
During the implementation of Quick Test framework, Peter, while writing an integer to string conversion function, came up with a code pattern that is common in REBOL, but wasn’t planned for Red/System: declaring private functions inside a function to hide them from global context. The pattern looked like this:
prin-int: func [...][ ... prin-digit: func [...][...] ... prin-digit ... ... ]
I was surprised when I tested the code he sent me, as I never did anything in the implementation to support such case explicitly. It was working because of a side-effect caused by the way functions are compiled in Red/System: the functions bodies are all gathered and compiled at the end of the global context code, regardless of where they are defined. The side-effect making the inner “prin-digit” function private is caused by a global function variable being declared inside a local scope, but without being part of the function specification block. So, once the outer function compiled, the “prin-digit” symbol is lost, making the function unreachable from global context and forever hidden.
I was thinking about adding a way for users to create private contexts much later in the future (relying on Red/System source header), but we have the opportunity to have an equivalent feature, right now and without adding anything to the code! So, I am giving it some time to see if the side-effect can be safely made permanent to keep that feature, and in the meantime, added it to the Possible Evolutions part of the specifications.
In the next days, I will work on:
In my next blog article, I will give an overview of Red/System compiler internals as requested by some followers.