[plt-scheme] verifying whether a symbol is defined at compile time?

From: jos koot (jos.koot at telefonica.net)
Date: Sun Apr 22 07:22:49 EDT 2007

If you are interested in module top level bindings only, you'll have to:

0: keep record of module top level variables (e.g. in a hash table)
1: Redefine syntax define such as to recognize whether or not it is a module top level define by means of procedure 
syntax-local-context. If it does not return a top level, expand to normal define. If the define form is at top level, consult the 
record of variables and act accordingly.
2: You also may want to redefine define-values in this way.
3: The above should be done in a separate module defining a complete language (i.e. all of mzscheme except the define forms, which 
can be exported by (provide (rename ...))
4: Use the language as in (module module-name my-mzscheme-module language)

Example:

(module my-mzscheme-module-language mzscheme
 (require (only  (lib "etc.ss") namespace-defined?))
 (define-for-syntax top-var-hash (make-hash-table))

 (define-syntax (my-define stx)
  (syntax-case stx ()
   ((my-define (name . args) . body) #'(my-define name (lambda args . body)))
   ((my-define var value)
    (if
     (let ((binding-type (identifier-binding #'var)))
      (and binding-type  (not (eq? binding-type 'lexical))))
   #'(define var value))
     (let ((var-name (syntax-object->datum #'var)))
      (if (hash-table-get top-var-hash var-name (lambda () #f))
     #'(set! var value)
       (begin (hash-table-put! top-var-hash var-name #t)  #'(define var value)))))))

 (provide (all-from-except mzscheme define) (rename my-define define)))

(module use-my-mzscheme-module-language my-mzscheme-module-language
 (define a 1)
 (define a 2)
 (define (b x) (define y (add1 x)) y)
 (provide a b))

(module use mzscheme
 (require use-my-mzscheme-module-language)
 (printf "~a~n" a)
 (printf "~a~n" (b 2)))

(require use) ; prints: 2 newline 3 newline


(((((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: Yin-So Chen
  To: jos koot
  Cc: mzscheme Mailing List
  Sent: Sunday, April 22, 2007 12:32 PM
  Subject: Re: [plt-scheme] verifying whether a symbol is defined at compile time?


  Hi Jos -

  Thanks for the quick response and the helpful answer (the references/example are great).  My motivation for having a conditional 
define is to make it play nice with the module system, which doesn't work well when having multiple definitions with the same name. 
I was hoping there is an "automated" way of detecting whether a symbol is already defined in the current module, if so, either 
override or not import the definition.

  Of course this is probably circumventing module's design (seems that module is *a lot* stricter than REPL by design), but I am 
certainly curious on how this could be done.  Seems like that compiler would have to keep symbol table(s) internally for all of the 
defined symbols in order to throw the "already defined" error... ;)

  Thanks,
  yinso



  On 4/22/07, jos koot <jos.koot at telefonica.net> wrote:
    Oops, the contra-example should read:

    (require (lib "etc.ss"))

    (define-syntax my-define
     (syntax-rules ()
      ((my-define (name . args) . body) (my-define name (lambda args . body)))
      ((my-define var value)
       (define var ; <== correction
        (begin
         (printf "my-define ~a status is ~s~n" 'var
          (if (namespace-defined? 'var) 'defined 'undefined))
         value)))))

    (if (read) (namespace-set-variable-value! 'b 2))
    (my-define b 2)

    Jos Koot



  -- 
  http://www.yinsochen.com
  ...continuous learning... 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20070422/80d4c9c5/attachment.html>

Posted on the users mailing list.