1

我的项目有一个实验,基本上,我需要在代码中嵌入一些 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 binding 在 5.3.1 版本上会因为某种原因崩溃,但它在 5.2.1 版本上大部分都可以工作

4

3 回答 3

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)))
于 2012-11-17T12:06:43.020 回答
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)

可能是你想要的,但可能不是。

于 2012-11-17T16:55:37.097 回答
1

老实说,我不明白你到底想达到什么目的。引用 N. Holm,Sketchy Scheme,第 4.5 版,p。108:»准引用的主要目的是构建仅包含几个可变部分的固定列表结构«。我认为不会在您所针对的上下文中使用准引用。

对于 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)
于 2012-11-17T09:37:39.220 回答