REBOL 3.0

Separating system and user contexts

Carl Sassenrath, CTO
REBOL Technologies
14-Jul-2009 15:26 GMT

Article #0219
Main page || Index || Prior Article [0218] || Next Article [0220] || 2 Comments || Send feedback

Part of the PITL (programming in the large) model is not to mix "the system" with "the program". That is, the system has its own context, as does the user's program. This philosophy is just a logical extension of the module context rule. (Each module gets its own context.)

Long ago I warned that this "split" would occur. At first it may feel a bit like wearing new shoes, but I hope it won't take long for you to "break it in" and get comfortable.

Let me get you started with a simple example. Boot REBOL and type:

>> print "hello"
hello

Seems good, works great. But, behind the scenes, what really happened? Here's a summary:

  1. You entered a line of text.
  2. The text was LOADed, converting it to a block consisting of a word and a string.
  3. As part of the LOAD, the block was RESOLVEd against the system exports context. It found the print word and imported a reference to it.
  4. The block was evaluated, print gets called and the string is output.

Now, let's take a look at the user context. It can be seen nicely this way:

>> ? system/contexts/user

SYSTEM/CONTEXTS/USER is an object of value:
   system          object!   [product version build license catalog context
   quit            native!   Stops evaluation and exits the interpreter.
   print           native!   Outputs a value followed by a line break.
   ?               function! Prints information about words and values.
   contexts        unset!    none
   user            unset!    none

There you can see the words you've used including that help (?) function and the path to the user context.

Of course, you can also type:

>> words-of system/contexts/user
== [system quit print ? contexts user words-of]

I can hear you asking "why are system and quit there?" Those were pre-imported into the user context. For system, it will become clear very soon (in a new article) why it's there. For quit, it's just for testing, and we may remove it later.

To show the decoupling of the user context, take a look at this example. It shows that probe uses print. Then, it sets print to NONE, but probe keeps working just fine:

>> probe :probe
make function! [[
   {Debug print a molded value and returns that same value.}
   value [any-type!]
][
   print mold :value
   :value
]]

>> print: none  ; in R2, you would never do this!

>> probe :probe
make function! [[
   {Debug print a molded value and returns that same value.}
   value [any-type!]
][
   print mold :value
   :value
]]

This code has redefined print locally in the user context, but that has no affect on probe which lives in the system context and uses the system's definition of print, not the user's.

At first, you may be a bit alarmed by this example! But, actually, this is an important part of the PITL model. You can now change your local definitions, even for system functions, without affecting the system itself.

Remember in R2 what happened when you did this:

>> system: none

Crash! Well, try that now, and the system will work just fine.

The R3 A71 build includes this change. It is just the starting point for you to begin testing.

2 Comments

REBOL 3.0
Updated 22-Jul-2017 - Edit - Copyright REBOL Technologies - REBOL.net