0

我有以下方案功能:

(define get-ivars
  (λ (ivars num)
    (cond ((null? ivars) '())
          (else
           (append (list (car ivars) `(nth args ,num)) (list (get-ivars (cdr ivars) (+ num 1))))))))

在特定实例中返回以下内容:

(x (nth args 1) (y (nth args 2) ()))

问题是,我需要它返回:

((x (nth args1)) (y (nth args 2)) ())

- 最后的两个右括号应该在 (nth 语句之后。

我将如何让它正常工作?

get-ivars 调用者:

(define gen-classes
  (λ (classes)
    (cond ((null? classes) '())
          (else
           (let* ((class (car classes)))
             (eval
              `(define ,(cadr class)
                 (λ (args)
                   (let (
                          ,(get-ivars (cdr (cadddr class)) 1)
                          )
                     (eval
                      (let* ,(cdar (cddddr class))
                        (λ (method . args)
                          ,(get-methods (cdadr (cddddr class)))
     ))))))))))))
4

2 回答 2

1

(list ...)你的条款中的第二个else是什么让你搞砸了。它将每个连续的调用嵌套得越来越深。递归自然会创建列表;你不需要再次包装它。

尝试:

(define get-ivars
  (λ (ivars num)
    (if (null? ivars) '()
      (cons (list (car ivars) `(nth args ,num)) 
            (get-ivars (cdr ivars) (+ num 1))))))

关于get-ivars调用者代码,围绕未引用调用的括号get-ivars是给您在评论中提到的麻烦的原因。有了他们,这段代码:

`(define ClassName
   (lambda (args)
     (let (,(get-ivars '(iVar1 iVar2 iVar3) 1))
       ;; your method-getting code
       )))

给你这个:

(define ClassName
  (lambda (args)
    (let (((iVar1 (nth args 1))
           (iVar2 (nth args 2))
           (iVar3 (nth args 3))))
      ;; method-getting code
     )))

如您所见,它在 let 中的分配周围为您提供了一组额外的括号。

所以你想这样做:

`(define ClassName
   (lambda (args)
     (let ,(get-ivars '(iVar1 iVar2 iVar3) 1)
        ;; your method-getting code
      )))

get-ivars正在返回一个列表列表,这正是您想要的 中的分配let,因此您不需要包装或(如我之前所说的)拼接它。只需单独使用 unquote,结果是:

(define ClassName
  (lambda (args)
    (let ((iVar1 (nth args 1))
          (iVar2 (nth args 2))
          (iVar3 (nth args 3)))
      ;; method-getting code
     )))

哪个应该可以解决问题。

顺便说一句,我发现eval当我在玩这个的时候把它去掉很有帮助;然后可以直观地检查结果以确保其语法正常。

于 2011-03-08T06:19:15.447 回答
0

我还没有尝试过,但我认为这会起作用:

(define (get-ivars ivars num)
    (if (null? ivars)
    '()
    (list (list (car ivars) `(nth args ,num))
          (get-ivars (cdr ivars) (1+ num)))))
于 2011-03-08T06:13:14.137 回答