在Guile Scheme中使用动态评估的变量名设置alist

时间:2014-09-28 00:55:52

标签: scheme eval guile

目前,我有以下列表:

(define globals '((objects test)))

其变量的名称存储在另一个alist中:

(define test '((loc globals) (other properties)))

我想在globals中轻松检索对象列表。我第一次尝试了这段代码。

(assoc 'objects
       (cadr (assoc 'loc
                    test)))

然而,这会吐出错误:

  

错误:在过程assoc中:位置2中的错误类型参数(期望关联列表):全局

我搜索并找到this question,所以我尝试使用eval。

(assoc 'objects
       (eval '(cadr (assoc 'loc
                           test))
             (interaction-environment)))

然而,吐出与上面相同的错误!有谁知道如何使用正确的参数调用assoc?

编辑(2014-10-27 21:27 EST):感谢您提供所有解决方案。遗憾的是,提交的示例可能无法在完整代码中使用:

(define-syntax object
  (syntax-rules ()
    ((_ name prop prop* ...)
     (begin
       (define name '(prop prop* ...))
       (let* ((parent (cadr (assoc 'loc name)))
              (objref (cdr (assoc 'objects parent))))
         (set! parent
               (assoc-set! parent
                           'objects
                           (append objref '(name)))))))))

(object my-object 
        (loc globals) 
        (name "Harry") 
        (desc "My Object"))

1 个答案:

答案 0 :(得分:1)

试试这个:

(define globals '((objects test)))    
(define test (list (list 'loc globals) '(other properties)))
; alternatively: (define test (list `(loc ,globals) '(other properties)))

(assoc 'objects
       (cadr (assoc 'loc test)))

=> '(objects test)

在这种情况下,我们不想创建符号列表,例如:

'(loc globals)

我们想要的是一个列表,其第二个元素是另一个名为globals的列表:

(list 'loc globals)

或者(正如Chris在评论中指出的那样)我们可以使用quasiquoting明确表示我们想要列表中的实际值,而不是我们忘记引用一个项目:

`(loc ,globals)

<强>更新

这是一个不同的问题,你应该从一开始就提到整个背景。问题中仍然缺少assoc-set!程序,但您可以尝试查看它是否符合您的要求:

(define-syntax object
  (syntax-rules ()
    ((_ name prop prop* ...)
     (begin
       (define name '(prop prop* ...))
       (let* ((parent (eval (cadr (assoc 'loc name)))) ; use Guile's eval
              (objref (cdr  (assoc 'objects parent))))
         (set! parent
               (assoc-set! parent
                           'objects
                           (append objref '(name)))))))))