;; Define a namespace. It automatically defines:
;; + symbol-test
;; + (setf symbol-test)
;; + unbound-test
;; + test-boundp
(define-namespace test)
;; result type of the accessor can be added (optionally) for the increased efficiency.
(define-namespace test fixnum)
(setf (symbol-test 'a) 0)
(print (symbol-test 'a)) ; --> 0
(print (symbol-test 'b)) ; --> error: UNBOUND-TEST signalled
(test-boundp 'a) ; --> t
;; flet-style lexical binding constructs specialized to that namespace
(let (x)
(test-let ((a 1))
(setf x
(lambda ()
(symbol-test 'a))))
(is (= 1 (funcall x))))
;; Expands into:
;; (PROGN
;; (LET ((#:TEMP1953 1))
;; (DECLARE (TYPE (TEST-TYPE) #:TEMP1953))
;; (MACROLET ((SYMBOL-TEST (&WHOLE LISP-NAMESPACE::WHOLE LISP-NAMESPACE::X)
;; (IF (EQUAL LISP-NAMESPACE::X ''A)
;; '#:TEMP1953
;; LISP-NAMESPACE::WHOLE)))
;; (PROGN (SETF X (LAMBDA () (SYMBOL-TEST 'A)))))))
;; note that the argument should be lexically identifiable.
(symbol-test 'a) ; --> 0
(nslet ((#'x (y) (1+ y))
((macro x) (y) (1+ y))
((macro y) (y) (1+ y))
(#'x (y) (1+ y))
((label y) (y) (y y))
((symbol-macro sm) 0)
(b 0))
(let ((b 1))
(print :x)))
;; (PROGN
;; (FLET ((X (Y) (1+ Y)))
;; (MACROLET ((X (Y) (1+ Y))
;; (Y (Y) (1+ Y))) ; same kinds of bindings are merged
;; (FLET ((X (Y) (1+ Y)))
;; (LABELS ((Y (Y) (Y Y)))
;; (SYMBOL-MACROLET ((SM 0))
;; (LET ((B 0))
;; (PROGN
;; (LET ((B 1))
;; (PRINT :X))))))))))
;; Lexical binding
(funcall
(namespace-let (((test a) 1))
(lambda ()
(symbol-test 'a)))) ; --> 1
;; (FUNCALL
;; (PROGN
;; (LET ((#:TEMP1976 1))
;; (MACROLET ((SYMBOL-TEST (&WHOLE WHOLE X)
;; (IF (EQUAL X ''A)
;; '#:TEMP1976
;; WHOLE)))
;; (PROGN (LAMBDA () (SYMBOL-TEST 'A)))))))