从库中导出填充的哈希表
这是一个导出哈希表的库。该库还包含填充哈希表的表达式:
(library (abc-1)
(export tbl)
(import (rnrs))
(define tbl (make-eq-hashtable))
(hashtable-set! tbl 'a 10)
(hashtable-set! tbl 'b 20)
(hashtable-set! tbl 'c 30))
这是该库的另一个版本,它导出可用于填充哈希表的过程:
(library (abc-2)
(export tbl init-tbl)
(import (rnrs))
(define tbl (make-eq-hashtable))
(define (init-tbl)
(hashtable-set! tbl 'a 10)
(hashtable-set! tbl 'b 20)
(hashtable-set! tbl 'c 30)))
采用第一种方法是否被认为是不好的形式?即拥有一个也执行任意表达式的库?这种方法有缺点吗?
相关问题...在库中,非定义表达式必须出现在定义之后。为了解决这个限制,我使用这个宏:
(define-syntax no-op-def
(syntax-rules ()
((_ expr ...)
(define no-op
(begin
expr
...)))))
例如:
(define t0 (make-eq-hashtable))
(no-op-def
(hashtable-set! t0 'a 10))
(define t1 (make-eq-hashtable))
(no-op-def
(hashtable-set! t1 'b 20))
同样,通过这个解决方法散布表达式和定义有缺点吗?
Here's a library which exports a hashtable. The library also contains expressions which populate the hashtable:
(library (abc-1)
(export tbl)
(import (rnrs))
(define tbl (make-eq-hashtable))
(hashtable-set! tbl 'a 10)
(hashtable-set! tbl 'b 20)
(hashtable-set! tbl 'c 30))
Here's another version of the library which exports a procedure which can be used to populate the hashtable:
(library (abc-2)
(export tbl init-tbl)
(import (rnrs))
(define tbl (make-eq-hashtable))
(define (init-tbl)
(hashtable-set! tbl 'a 10)
(hashtable-set! tbl 'b 20)
(hashtable-set! tbl 'c 30)))
Is it considered bad form to take the first approach? I.e. to have a library which also executes arbitrary expressions? Are there drawbacks to this approach?
A related issue... In a library, non-definition expressions must occur after definitions. To work around this constraint, I'm using this macro:
(define-syntax no-op-def
(syntax-rules ()
((_ expr ...)
(define no-op
(begin
expr
...)))))
for example:
(define t0 (make-eq-hashtable))
(no-op-def
(hashtable-set! t0 'a 10))
(define t1 (make-eq-hashtable))
(no-op-def
(hashtable-set! t1 'b 20))
Again, are there drawbacks to interspersing expressions and definitions via this workaround?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这两者都没有大问题。也许将
no-op
更改为dummy
以澄清它是一个从未使用过的绑定。顶级副作用表达式的唯一可能的问题是,在某些实现中,当您认为它们应该执行时,它们可能不会被执行。 R6RS 允许“隐式定相”,这意味着您只需导入一些库,语言就会根据其标识符的使用位置将其置于正确的阶段。因此,在这样的实现中(例如,Ikarus),如果您只是导入一个库但不使用它的标识符,则该库不会被实例化 - 因此,一个仅用于在导入时打印一些内容的库不会这样做所以除非它还导出一些绑定,并且导入方在某处提到该绑定。
但这对你来说不是问题。
There are no big problems with either of these. Maybe change
no-op
todummy
to clarify that it's a binding that is never used.The only possible issue with toplevel side-effect expressions is that in some implementations they might not be executed when you think they should. R6RS allows "implicit phasing", which means that you just import some library and the language gets it into the correct phase depending on where its identifiers are used. So, in such an implementation (eg, Ikarus), if you just import a library but not use its identifiers, the library wouldn't be instantiated -- so a library that is simply used to print some stuff when it's imported will not do so unless it's also exporting some binding, and the importing side is mentioning that binding somewhere.
But that won't be an issue in your case.