[racket] Eval, namespaces redefinitions, and (maybe) code-inspectors
Racketeers,
I'm working through eval, namespace, and syntactical macros
My question concerns re-definition of identifiers.
I've worked through three cases below, demonstrating Racket's default
behavior.
Case 1 shows that identifiers defined at module (or is it top?) level
cannot be redefined at namespace level
Case 2 shows that identifiers defined at namespace level *can* be
redefined at namespace level
Case 3 shows that the re-definition allowed in Case 2 can be prevented
by using namespace introspection
But, is there a better way to prevent re-defining identifiers with
namespace-level binding?
Can I parameterize the namespace to prevent re-definition of
namespace-level variables? Perhaps using code-inspectors?
Thanks very much.
R./
Zack
;===Demonstration Code: (3 Cases) =============================
#lang racket
(require rackunit)
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
;====CASE 1 identifier which is defined at module-level cannot be
redefined at namespace level=====
(define-syntax-rule (my-define ([id val]))
(define id val))
(define x 10)
(eval '(my-define ((x 1))) ns)
; ERROR cannot re-define a constant
;CASE 2 identifier defined at namespace level CAN be redefined at
namespace level
(define-syntax-rule (my-define ([id val]))
(define id val))
(eval '(my-define ((x 10))) ns)
(check-equal? (eval 'x ns) 10)
(eval '(my-define ((x 20))) ns)
(check-equal? (eval 'x ns) 20)
;===CASE 3 use introspection to prevent re-definition ====
(define-syntax-rule (my-define-v2 ([id val]))
(begin
(when (memq 'id (namespace-mapped-symbols ns))
(error (format "~A already defined as ~A in this namespace\n"
'id id)))
(define id val)))
(eval '(my-define-v2 ((x 10))) ns)
(eval '(my-define-v2 ((x 20))) ns)
;ERROR: x already defined as 10 in this namespace