To illustrate Lutz' description of the read/compile/evaluate process some session:
Code: Select all
newLISP v.10.5.4 64-bit on Linux IPv4/6 UTF-8 libffi, options: newlisp -h
>
;; # (1) (2) ..
(define (create-funcs)
(println "in create-funcs")
(context 'C)
(define (f_1) 1)
(context MAIN))
;; .. (1) (2) #
;;
"(dolist (s (symbols) (= (string s) \"f_1\")))"
(dolist (s (symbols) (= (string s) "f_1")))
"-> 'f_1 symbol exists in MAIN, but .."
;;
"f_1"
f_1
"-> .. is nil: function not defined yet"
;;
;; # (3) (4) ..
"(create-funcs)"(create-funcs)
;; .. (3) (4) #
;;
"(symbols 'C)"
(symbols 'C)
"-> no C:f_1, but .."
;;
"(f_1)"
(f_1)
"-> .. call in MAIN by (f_1) works!"
(lambda () (println "in create-funcs") (context 'C)
(define (f_1)
1)
(context MAIN))
"(dolist (s (symbols) (= (string s) \"f_1\")))"
true
"-> 'f_1 symbol exists in MAIN, but .."
"f_1"
nil
"-> .. is nil: function not defined yet"
"(create-funcs)"
in create-funcs
MAIN
"(symbols 'C)"
()
"-> no C:f_1, but .."
"(f_1)"
1
"-> .. call in MAIN by (f_1) works!"
>
Some inferred rules regarding context switches:
- (top-level) outside lambdas/maccros:
- control symbol creation at compile time;
- (lower-level) inside lambdas/macros:
- control creation of new symbols at evaluation time;
- do not affect symbol creation at compile time;
- do not change symbols already created at compile time.
The core point here:
only top-level context switches will be honored at
compile time, but not lower-level ones.
An example for a top-level context switch controlled by some evaluation:
Code: Select all
(if flag
(context 'C_1)
(context 'C_2))
(define (create-funcs)
(define (f) 1))
(context MAIN)
The flag controls, in which context symbol
f will be created at compile time.
The following does not work as one might expect:
Code: Select all
(define (switch-context flag)
(if flag
(context 'C_1)
(context 'C_2)))
(switch-context nil)
(define (create-funcs)
(define (f) 1))
(create-funcs)
(context MAIN)
Here
f becomes
MAIN:f instead of
C_2:f (context
C_2 will be created, though).
Leaving a function goes back to the context of the caller; seen by evaluating the following:
Code: Select all
(define (goto-context-inner flag)
(if flag
(context 'C_2)
(context 'C_1))
(println "inner: " (context)))
(define (goto-context flag)
(if flag
(context 'C_1)
(context 'C_2))
(goto-context-inner flag)
(println "outer: " (context)))
(goto-context true)
(println "MAIN: " (context))
So calling a function for context switches at caller side (e.g. top-level) does not work.
In other words: context switches in callees do not propagate to callers (which is a good thing).