确定以编程方式定义哪些函数
determining which functions are defined programmatically
如果可用,我想将对特定函数集的调用替换为我的实现,例如:
(define (call-my-fn f . args)
(cond [(eq? f append) (apply my-append args)]))
我所有的实现都在一个单独的文件中,我不想继续添加到 cond
子句中。有没有办法我可以写这样的东西:
(require "my-fns.rkt")
(define (call-my-fn f . args)
(cond [(is-defined? f "my-fns.rkt") (apply "my-version-of-f" args)]))
dynamic-require
可用于动态查询其他模块中提供的变量。 dynamic-require
的第三个参数控制当查询的变量不存在时应该发生什么,所以你可以这样做:
;; lib.rkt
#lang racket
(provide foo bar)
(define foo #f)
(define (bar x) x)
;; client.rkt
#lang racket
(define does-not-exist (gensym))
(eq? (dynamic-require "lib.rkt" 'foo (λ () does-not-exist)) does-not-exist) ; #t
(eq? (dynamic-require "lib.rkt" 'bar (λ () does-not-exist)) does-not-exist) ; #t
(eq? (dynamic-require "lib.rkt" 'baz (λ () does-not-exist)) does-not-exist) ; #f
有人可能会尝试将上面的内容简化为
;; client.rkt
#lang racket
(dynamic-require "lib.rkt" 'foo (λ () #f)) ; #f
(dynamic-require "lib.rkt" 'bar (λ () #f)) ; #<procedure:bar>
(dynamic-require "lib.rkt" 'baz (λ () #f)) ; #f
如果您知道所有提供的标识符都未绑定到 #f
,这将起作用。但如果不是这种情况,它将给出如上所示的错误结果。该解决方案通过返回一个新的唯一符号 does-not-exist
来解决该问题,该符号仅 eq?
自身。然后,我们可以使用eq?
来测试返回值是否为does-not-exist
。如果是,那么我们可以确定没有提供标识符。
如果可用,我想将对特定函数集的调用替换为我的实现,例如:
(define (call-my-fn f . args)
(cond [(eq? f append) (apply my-append args)]))
我所有的实现都在一个单独的文件中,我不想继续添加到 cond
子句中。有没有办法我可以写这样的东西:
(require "my-fns.rkt")
(define (call-my-fn f . args)
(cond [(is-defined? f "my-fns.rkt") (apply "my-version-of-f" args)]))
dynamic-require
可用于动态查询其他模块中提供的变量。 dynamic-require
的第三个参数控制当查询的变量不存在时应该发生什么,所以你可以这样做:
;; lib.rkt
#lang racket
(provide foo bar)
(define foo #f)
(define (bar x) x)
;; client.rkt
#lang racket
(define does-not-exist (gensym))
(eq? (dynamic-require "lib.rkt" 'foo (λ () does-not-exist)) does-not-exist) ; #t
(eq? (dynamic-require "lib.rkt" 'bar (λ () does-not-exist)) does-not-exist) ; #t
(eq? (dynamic-require "lib.rkt" 'baz (λ () does-not-exist)) does-not-exist) ; #f
有人可能会尝试将上面的内容简化为
;; client.rkt
#lang racket
(dynamic-require "lib.rkt" 'foo (λ () #f)) ; #f
(dynamic-require "lib.rkt" 'bar (λ () #f)) ; #<procedure:bar>
(dynamic-require "lib.rkt" 'baz (λ () #f)) ; #f
如果您知道所有提供的标识符都未绑定到 #f
,这将起作用。但如果不是这种情况,它将给出如上所示的错误结果。该解决方案通过返回一个新的唯一符号 does-not-exist
来解决该问题,该符号仅 eq?
自身。然后,我们可以使用eq?
来测试返回值是否为does-not-exist
。如果是,那么我们可以确定没有提供标识符。