The 'context' primitive works like a compile directive controlling the creation of symbols in certain context while parsing newLISP source code. Use the 'context' primitive only on the toplevel, but don't switch context on runtime. If you have to refer to a symbol in a different context during runtime use i.e.:
(set 'MYCTX:var 123)
this could be embedded in a function without a problem
(define (OTHER:proc) .......)
would define proc in the context OTHER, but variables used in OTHER:proc would all refer to the context under which the (define (OTHER:proc) ...) was compiled.
(symbols 'ACTX) ; get all the symbols contained in context 'ACTX.
Imagine the following program:
(define (run) (context 'CTX) (set 'var 123))
MAIN:var => 123
when you run this program, the comand prompt will come back with the context CTX. Because the statement (context 'CTX) switched the "current" context to CTX. But the variable "var" was still compiled under the context 'MAIN, when the function was loaded from a file or entered on the command line. the symbol "var" will be part of MAIN and not CTX.
But now lets load the following program (or enter it on the commandline):
(define (run) (context 'CTX) (eval-string "(set 'var 123)"))
CTX:var => 123
At this time "var" will be created in the context CTX and not in MAIN. Because "var" doesn't get compiled until runtime of the function 'run' because the compilation is done by the 'eval-string' statement. Now at runtime the "compile context" gets switched to CTX and has an effect on the 'eval-string' statement.
Another more complete example:
(context 'CTX) ;; step A
(set 'var 123) ;; step B
(context 'MAIN) ;; step C
(define (run) (context 'CTX) (set 'var 999)) ;; step D
(run) ;; step E
CTX:var => 123
MAIN:var => 999
step B: At this time CTX:var will be set to 123.
step D: At this time MAIN:var will be created
step E: At this time MAIN:var will be set to 999 and CTX:var stays 123
also after E the current compile context is switched to CTX (not after step D, but after step E)
The function 'symbols' aleays reports the symbols of the "compile context" that is why:
(define (run) (context 'CTX) (symbols))
will report the symbols in CTX. You can use (symbols 'CTX) to accomplish the same without switching contexts.
The background of all this is the fact that newLISP is not and interpreted language, but rather a compiled language. One S-expression at a time gets read in, compiled and then evaluated.
When you read in a function definition with 'define' all symbols occurring in that 'define' statement get compiled into the current context, which had been switched by a '(context 'BLAH) on the top level before. After that a 'define' function statement gets read then executed. Execution here means a lambda expression is produced for the symbol defined. It does not mean that the '(context 'XYZ)' statement, which happens to be part of the 'define' statement has been excuted. It doesn't go into effect until the defined function is called from somewhere.
If you want to switch contexts during function execution time, you really have to know what you are doing (changing the compile context). That is why I recommend using 'context' only on the toplevel. Functions like 'symbols', 'symbol' and 'save' can take an optional context argument.
PS: There is also a chapter about 'context' issues in the manual. This chapter talks about the fact that symbols may already have been created in MAIN by the time a context gets loaded compiled. In this case symbols occurring in context will refer to MAIN and not be newly created in the context. When in doubt what symbol is referred to, always prefix with the context name.