我怎样才能将表达式列表放到代码中?

时间:2012-11-17 05:27:06

标签: scheme racket

我的项目有一个实验,基本上,我需要嵌入一些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

3 个答案:

答案 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)

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