How do I test whether a variable is defined before referencing it?

前端 未结 3 1171
庸人自扰
庸人自扰 2021-02-09 15:04

I would like to be able to test whether a variable is defined, prior to accessing it.

I like to have a global that specifies a \"debug level\". If debug level is 0, no

3条回答
  •  孤街浪徒
    2021-02-09 15:36

    Clunky but workable solution for R5RS. Use the often neglect/forgotten ability of let-syntax to redefine keywords. this is clunky because your whole file is wrapped in a let-syntax and because it adds some overhead to each define. I use a associative list to remember definitions, a hash table would be a beter choice.

    (define define-list '())
    (define define-list-add 
      (lambda (key value)
        (set! define-list (cons `(,key ,value) define-list))))
    
    (let-syntax (
                 (define (syntax-rules ()
                           ((_ (pro-name args ...) body ...) 
                            (begin
                              (define (pro-name args ...) body ...)
                              (define-list-add pro-name  '((pro-name args ...) body ...))))
                           ((_ pro-name pro) (begin
                                               (define pro-name pro)
                                               (define-list-add 'pro-name 'pro)))
    
                           ))
                 (defined?
                   (syntax-rules ()
                     ((_ sym) (begin (if (assoc (quote sym) define-list) #t #f)))))
                 )
      (define y (lambda () x))
    
      (display (defined? y))
      (newline)
      (display (defined? x))
      )
    

    prints

    #t
    #f
    

    Below in racket: a module is used to redefine define to store each symbol and definition in a list called define-list. The macro defined? looks in this list to see if weather or not the symbol has been defined.

    (module qdefine mzscheme
      (provide ;(all-from-except mzscheme let)
       (rename define olddefine)
       (rename quote-define define)
       defined?)
    
      (define define-list '())
      (define define-list-add 
        (lambda (key value)
          (set! define-list (cons `(,key ,value) define-list))))
    
      (define-syntax quote-define
        (syntax-rules ()
          ((_ (pro-name args ...) body ...) 
           (begin
             (define (pro-name args ...) body ...)
             (define-list-add pro-name  '((pro-name args ...) body ...))))
          ((_ pro-name pro) (begin
                              (define pro-name pro)
                              (define-list-add 'pro-name 'pro)))
    
          ))
    
      (define-syntax defined?
        (syntax-rules ()
          ((_ sym) (begin (if (assoc (quote sym) define-list) #t #f)))))
      )
    (require 'qdefine)
    
    (define y (lambda () x))
    
    (defined? y)
    (defined? x)
    

    In guile it is just defined? apparently: http://www.delorie.com/gnu/docs/guile/guile_289.html

提交回复
热议问题