[plt-scheme] namespace-variable-value

From: jos koot (jos.koot at telefonica.net)
Date: Thu May 3 07:10:03 EDT 2007

Hi Wayne,
I have been away for some days. Therefore I could not respond earlier. I hope others have cleared up things in the meantime. You can 
try "identifier-binding" as follows:

(module a mzscheme
 (define-struct not-defined ())
 (define undefined? not-defined?)
 (define undefined (make-not-defined))
 (define-syntax (value/binding stx)
  (syntax-case stx ()
   ((value/binding symbol)
    (let ((binding-type (identifier-binding #'symbol)))
   #`(values
    #,(cond
       ((eq? binding-type 'lexical) #'symbol)
       ((not binding-type) #'(namespace-variable-value 'symbol #t (lambda () undefined)))
       (else  #'symbol))
    '#,binding-type)))))
 (provide value/binding undefined?))

(module b mzscheme
 (define b 1)
 (provide b))

(require a b)
(define c 2)
(value/binding b) ; --> 1 (b b b b #f)
(value/binding c) ; --> 2 #f
(value/binding d) ; --> #<struct:not-defined> #f
(define d 3)
(value/binding d) ; --> 3 #f
(let ((e 4)) (value/binding e)) ; --> 4 lexical

(module x mzscheme
 (require a b)
 (define c 20)
 (define-syntax print-value/binding
  (syntax-rules ()
   ((print-value/binding x)
    (apply printf "~s ~s~n" (call-with-values (lambda () (value/binding x)) list)))))
 (print-value/binding b) ; prints 1 (b b b b #f)
 (print-value/binding c) ; 20 (#<module-path-index> c #<module-path-index> c #f)
 ; (print-value/binding d) ; error: reference to an identifier before its definition: d
 (define d 30)
 (print-value/binding d) ; 30 (#<module-path-index> d #<module-path-index> d #f)
 (let ((e 40)) (print-value/binding e))); prints 40 lexical

(require x)

Notice that the binding-type is determined at expansion/compilation time. Things may go wrong when a (current-namespace 
other-namespace) is done during execution time. Also notice that there are some subtle differences between modules and the top 
level. E.g, a module defined variable (d in the example) is seen in the module as being defined even above its definition, but it is 
not allowed to refer to this variable above its definition.
Jos

(((((lambda(x)((((((((x x)x)x)x)x)x)x)x))
    (lambda(x)(lambda(y)(x(x y)))))
   (lambda(x)(x)x))
  (lambda()(printf "Greetings, Jos~n"))))
  ----- Original Message ----- 
  From: support at taxupdate.com
  To: jos koot
  Cc: plt-scheme at list.cd.brown.edu
  Sent: Monday, April 30, 2007 1:00 PM
  Subject: Re: [plt-scheme] namespace-variable-value


  Jos,

  On Fri, Apr 27, 2007 at 09:55:15PM +0200, jos koot wrote:
  >   Why doesn't namespace-variable-value pick up the mapping in the current-namespace?

  > It does, but the current namespace is not used for the body of a module. Each module has its own special 'namespace' such as to
  > protect its variables and to make syntaxes hygienic by not confusing module variables and syntaxes with those of the importing
  > module (or the top level) MHO.

  Is there a way to determine if a given symbol has been defined/imported into a module's
  namespace (given only the symbol)?  For example:

  (module x mzscheme
      (require ...)

      ;; test whether sym is defined or mapped to a value:
      (define (defined/imported sym)
  ...)
  )

  It seems that namespace-variable-value almost does this, but for imported
  mappings, it would need the imported module name.

  Wayne
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20070503/dedd1eaa/attachment.html>

Posted on the users mailing list.