Macros 如何编写一个scheme宏来定义一个变量,并以字符串的形式获取该变量的名称?
这主要是一个后续行动。我决定只记住YAGNI,并创建了一个全局变量(Macros 如何编写一个scheme宏来定义一个变量,并以字符串的形式获取该变量的名称?,macros,scheme,Macros,Scheme,这主要是一个后续行动。我决定只记住YAGNI,并创建了一个全局变量(libpython)。我最初将其设置为#f,然后设置为。我添加了一个函数,用于检查该值是否已初始化: (define (get-cpyfunc name type) (lambda args (if libpython (apply (get-ffi-obj name libpython type) args) (error "Call init before using
libpython
)。我最初将其设置为#f
,然后设置为当调用init
时,code>。我添加了一个函数,用于检查该值是否已初始化:
(define (get-cpyfunc name type)
(lambda args
(if libpython
(apply (get-ffi-obj name libpython type) args)
(error "Call init before using any Python C functions"))))
所以现在我要做的是。我想定义一个宏,该宏将采用以下内容:
(define-cpyfunc Py_Initialize (_fun -> _void))
并将其转换为:
(define Py_Initialize (get-cpyfunc "Py_Initialize" (_fun -> _void)))
我一直在阅读宏文档,试图弄明白这一点,但我似乎无法找到一种方法使其工作。有人能帮我吗(或者至少让我大致了解一下宏的样子)?或者,有没有一种方法可以在没有宏的情况下执行此操作?为什么不将生成的代码更改为
(define Py_Initialize (get-cpyfunc 'Py_Initialize (_fun -> _void)))
然后让获取cpyfunc
运行(符号->字符串名)
诚然,可能有一种方法可以用语法case
实现这一点(尽管我永远记不起它的语法),而且如果您使用的是CL-esquedefine macro的方案,这并不是完整的答案,但我提出了一个满足这两个要求的宏(定义变量和具有该变量名称的字符串):
我在另一个问题中回答了这个问题的大部分(我没有看到这个)。使用像这样提取绑定的函数是可以的,但这里可能存在的一个问题是,由于您仅在调用结果函数时生成绑定,因此每次调用时都会重新创建此绑定。快速解决此问题的简单方法是使用承诺,类似以下内容:
(require scheme/promise)
(define (get-cpyfunc name type)
(define the-function
(delay (if libpython
(get-ffi-obj name libpython type)
(error "Call init before using any Python C functions"))))
(lambda args (apply (force the-function) args)))
但这与我在上一个问题中发布的代码基本相同
更多随机注释:
get ffi obj
将接受一个符号作为绑定到的名称——这是有意的,目的是简化此类宏(如上一个问题中所述)
- 在宏中使用
(symbol->string'name)
是可以的。正如我在上面对Nathan评论的回复中所指出的,这意味着它会在运行时被调用,但mzscheme应该能够优化它,所以不需要尝试编写一些复杂的宏来在编译时执行此任务
- 查看PLT目录——您将发现一个名为
ffi
的集合。这是一个具有各种样式的绑定示例集合。创建绑定的宏在这些示例中非常常见
我想这是一种方法。我没有想到。我记不太清楚语法大小写
符号字符串是在宏展开时运行还是在运行时运行?不在这里,因为symbol->string
是生成代码的一部分(在模板内)。感谢您指出这些示例!我只是想有更多使用ffi
的示例。
(require scheme/promise)
(define (get-cpyfunc name type)
(define the-function
(delay (if libpython
(get-ffi-obj name libpython type)
(error "Call init before using any Python C functions"))))
(lambda args (apply (force the-function) args)))