s) v)
             (loop (cdr pos)))))
  (or (fn m v)
      (loop (module-uses m))))


;;; {Is a symbol bound in a module?}
;;;
;;; Symbol S in Module M is bound if S is interned in M and if the binding
;;; of S in M has been set to some well-defined value.
;;;

(define (module-locally-bound? m v)
  "Is symbol V bound (interned and defined) locally in module M?"
  (let ((var (module-local-variable m v)))
    (and var
         (variable-bound? var))))

(define (module-bound? m v)
  "Is symbol V bound (interned and defined) anywhere in module M or its
uses?"
  (let ((var (module-variable m v)))
    (and var
         (variable-bound? var))))

;;; {Is a symbol interned in a module?}
;;;
;;; Symbol S in Module M is interned if S occurs in
;;; of S in M has been set to some well-defined value.
;;;
;;; It is possible to intern a symbol in a module without providing
;;; an initial binding for the corresponding variable.  This is done
;;; with:
;;;       (module-add! module symbol (make-undefined-variable))
;;;
;;; In that case, the symbol is interned in the module, but not
;;; bound there.  The unbound symbol shadows any binding for that
;;; symbol that might otherwise be inherited from a member of the uses list.
;;;

(define (module-obarray-get-handle ob key)
  ((if (symbol? key) hashq-get-handle hash-get-handle) ob key))

(define (module-obarray-ref ob key)
  ((if (symbol? key) hashq-ref hash-ref) ob key))

(define (module-obarray-set! ob key val)
  ((if (symbol? key) hashq-set! hash-set!) ob key val))

(define (module-obarray-remove! ob key)
  ((if (symbol? key) hashq-remove! hash-remove!) ob key))

(define (module-symbol-locally-interned? m v)
  "Is symbol V interned (not neccessarily defined) locally in module M
or its uses?  Interned symbols shadow inherited bindings even if they
are not themselves bound to a defined value."
  (not (not (module-obarray-get-handle (module-obarray m) v))))

(define (module-symbol-interned? m v)
  "Is symbol V interned (not neccessarily defined) anywhere in module M
or its uses?  Interned symbols shadow inherited bindings even if they
are not themselves bound to a defined value."
  (module-search module-symbol-locally-interned? m v))


;;; {Mapping modules x symbols --> variables}
;;;

;; module-local-variable module symbol
;; return the local variable associated with a MODULE and SYMBOL.
;;
;;; This function is very important. It is the only function that can
;;; return a variable from a module other than the mutators that store
;;; new variables in modules.  Therefore, this function is the location
;;; of the "lazy binder" hack.
;;;
;;; If symbol is defined in MODULE, and if the definition binds symbol
;;; to a variable, return that variable object.
;;;
;;; If the symbols is not found at first, but the module has a lazy binder,
;;; then try the binder.
;;;
;;; If the symbol is not found at all, return #f.
;;;
;;; (This is now written in C, see `modules.c'.)
;;;

;;; {Mapping modules x symbols --> bindings}
;;;
;;; These are similar to the mapping to variables, except that the
;;; variable is dereferenced.
;;;

(define (module-symbol-local-binding m v . opt-val)
  "Return the binding of variable V specified by name within module M,
signalling an error if the variable is unbound.  If the OPT-VALUE is
passed, then instead of signalling an error, return OPT-VALUE."
  (let ((var (module-local-variable m v)))
    (if (and var (variable-bound? var))
        (variable-ref var)
        (if (not (null? opt-val))
            (car opt-val)
            (error "Locally unbound variable." v)))))

(define (module-symbol-binding m v . opt-val)
  "Return the binding of variable V specified by name within module M,
signalling an error if the variable is unbound.  If the OPT-VALUE is
passed, then instead of signalling an error, return OPT-VALUE."
  (let ((var (module-variable m v)))
    (if (and var (variable-bound? var))
        (variable-ref var)
        (if (not (null? opt-val))
            (car opt-val)
            (error "Unbound variable." v)))))


