我的项目有一个实验,基本上,我需要嵌入一些s-expression到代码中并让它运行,就像这样,
(define (test lst)
(define num 1)
(define l (list))
`@lst) ; oh, this is not the right way to go.
(define lst
`( (define num2 (add1 num))
(displayln num2)))
我希望test
功能类似于球拍代码中的test(lst)
:
(define (test lst)
(define num 1)
(define l (list))
(define num2 (add1 num)
(displayln num2))
我怎样才能在球拍中做到这一点?
更新
我想使用eval
或之前的问题的原因是我使用Z3球拍绑定,我需要生成公式(使用球拍绑定API),然后我会在某些时候触发查询,这是当我需要评估这些代码时。
在我的情况下,我还没有想出其他方法......
一个非常简单的例子是,想象
(let ([arr (array-alloc 10)])
(array-set! arr 3 4))
我有一些模型来分析构造(所以我没有直接使用racketZ3),在每个分析点,我会将程序中的数据类型映射到Z3类型,并做出一些断言,
我将生成如下内容:
在分配网站,我需要制定以下公式:
(smt:declare-fun arr_z3 () IntList)
(define len (make-length 10))
然后在数组设置站点,我将有以下断言并检查3是否小于长度
(smt:assert (</s 3 (len arr_z3)))
(smt:check-sat)
最后,我将收集上面生成的公式,并将它们包装在能够触发Z3绑定的表单中,以运行以下收集的信息作为代码:
(smt:with-context
(smt:new-context)
(define len (make-length 10))
(smt:assert (</s 3 (len arr_z3)))
(smt:check-sat))
这是我能想到的超级简单的例子......有意义吗? 旁注。由于某些原因,Z3 Racket绑定在版本5.3.1上会崩溃,但它主要适用于版本5.2.1
答案 0 :(得分:1)
老实说,我不明白你想要达到什么目标。引用N. Holm,Sketchy Scheme,第4.5版,p。 108:»准报价的主要目的是构建仅包含少量可变部分的固定列表结构«。我认为quasiquotation不会像你所瞄准的那样在上下文中使用。
对于quasiquotation的典型上下文,请考虑以下示例:
(define (square x)
(* x x))
(define sentence
'(The square of))
(define (quasiquotes-unquotes-splicing x)
`(,@sentence ,x is ,(square x)))
(quasiquotes-unquotes-splicing 2)
===> (The square of 2 is 4)
答案 1 :(得分:1)
警告:如果您不熟悉Scheme中函数的工作原理,请忽略答案!宏是一种高级技术,您需要首先了解函数。
听起来你在询问宏。这里有一些代码将test
定义为打印2
的函数:
(define-syntax-rule (show-one-more-than num)
(begin
(define num2 (add1 num))
(displayln num2)))
(define (test)
(define num1 1)
(show-one-more-than num1))
现在,我可以(并且应该!)将show-one-more-than
编写为函数而不是宏(如果将define-syntax-rule
更改为define
,代码仍然有效),但宏实际上通过在他们的呼叫站点生成代码来进行操作。所以上面的代码扩展为:
(define (test)
(define num1 1)
(begin
(define num2 (add1 num1))
(displayln num2)))
答案 2 :(得分:1)
如果不能更好地了解问题,很难说出解决这个问题的正确方法是什么。蛮力方法,如下:
#lang racket
(define (make-test-body lst)
(define source `(define (test)
(define num 1)
(define l (list))
,@lst))
source)
(define lst
`((define num2 (add1 num))
(displayln num2)))
(define test-source
(make-test-body lst))
(define test
(parameterize ([current-namespace (make-base-namespace)])
(eval `(let ()
,test-source
test))))
(test)
可能是你想要的,但可能不是。