On Feb 21, 2007, at 7:57 PM, Ian D. Leroux wrote:
1- The documentation for the 'block' declaration states that: "the compiler assumes that global variables defined in the current file that are not mutated in the file will never be mutated". Strictly interpreted, this means that any global variable that *is* mutated in the current file does not benefit from this declaration. In particular, using lexical scoping to hide private variables
(define (foo) 'forward) (define (bar) 'forward)
(let ( ... foo and bar's secret helper functions and variables ...) (set! bar the-real-bar) (set! foo the-real-foo))
would stymie the optimizer. Does it really work that way,
Yes. In this code
(declare (block))
(define foo 'forward) (define bar 'forward) (define baz values)
(let () (set! foo values) (set! bar values))
(define (f x) (foo x))
(define (g x) (baz x))
f compiles to
#undef ___PH_PROC #define ___PH_PROC ___H_f #undef ___PH_LBL0 #define ___PH_LBL0 3 #undef ___PD_ALL #define ___PD_ALL ___D_FP ___D_R4 #undef ___PR_ALL #define ___PR_ALL ___R_FP ___R_R4 #undef ___PW_ALL #define ___PW_ALL ___W_R4 ___BEGIN_P_COD ___BEGIN_P_HLBL ___DEF_P_HLBL_INTRO ___DEF_P_HLBL(___L0_f) ___DEF_P_HLBL(___L1_f) ___END_P_HLBL ___BEGIN_P_SW ___DEF_SLBL(0,___L0_f) ___IF_NARGS_EQ(1,___NOTHING) ___WRONG_NARGS(0,1,0,0) ___DEF_GLBL(___L_f) ___POLL(1) ___DEF_SLBL(1,___L1_f) ___JUMPGLOSAFE(___SET_NARGS(1),4,___G_foo) ___END_P_SW ___END_P_COD
so it calls foo, but g compiles to
#undef ___PH_PROC #define ___PH_PROC ___H_g #undef ___PH_LBL0 #define ___PH_LBL0 6 #undef ___PD_ALL #define ___PD_ALL ___D_FP ___D_R4 #undef ___PR_ALL #define ___PR_ALL ___R_FP ___R_R4 #undef ___PW_ALL #define ___PW_ALL ___W_R4 ___BEGIN_P_COD ___BEGIN_P_HLBL ___DEF_P_HLBL_INTRO ___DEF_P_HLBL(___L0_g) ___DEF_P_HLBL(___L1_g) ___END_P_HLBL ___BEGIN_P_SW ___DEF_SLBL(0,___L0_g) ___IF_NARGS_EQ(1,___NOTHING) ___WRONG_NARGS(0,1,0,0) ___DEF_GLBL(___L_g) ___POLL(1) ___DEF_SLBL(1,___L1_g) ___JUMPGLOSAFE(___SET_NARGS(1),6,___G_values) ___END_P_SW ___END_P_COD
which calls values directly.
or does the declaration imply a stronger assumption, such as no mutation of any bindings outside the current file?
2- Am I correct in interpreting the (not core) declaration as: "the following code is made available to the compiler in case it helps optimization, but this file is not responsible for providing it to outside clients and so the compiler can ignore it if it chooses"?
Yes. (You also need to (declare (block)), I believe.
3- Aside from mentioning a few of the associated error messages, the documentation doesn't discuss the namespace mechanism. Is it meant to be superseded by the R6RS library mechanism?
Don't know.
If not, does it have any problems that should discourage mere mortals from using it?
I find it tricky, but also very useful when it works.
On a related note, does the ##foo notation mean "use the compiler's native implementation/interpretation of foo, even if it has been redefined in the current namespace"?
An identifier beginning with ## is not a valid identifier in Scheme, so no valid Scheme program should redefine this function. I.e., it's valid Scheme to redefine +, but not ##+, which is the internal definition of (two argument) +.
I'm no expert (I think Marc is the only expert), but this is my understanding of things.
Brad