如何从lisp中的函数返回控制

时间:2010-09-28 04:03:45

标签: lisp common-lisp

(defun returnFirstCharacter(p)

(if (symbolp p) (char (symbol-name p) 0) nil)
)

 (defun returnRestCharacters (p)
(let ()
    (intern (subseq(string p) 1))
)         
)

 (defun val (x a)
  (cond ((null a) nil)
        ((equal (car(cdr a)) x) (cdr (cdar a)))
        (t (val x (cdr a)))
    )
 )



 (defun match (pattern data)
(cond 
    ((equal pattern data) t)
    ((match2 pattern data nil))
    (t nil)
)
 )

  (defun match2 (p d a)
(cond

    ( (null p)(cond 
                    ((null a) t)
                    (t a)
                )
    )

    ((numberp p) (cond 
                        ((equal p d) t) 
                        (t nil)
                    )
    ) 

    (  (symbolp p) (cond
                        ((alpha-char-p (returnFirstCharacter p))
                                    (let ()(if (equal p d) (match2 nil nil a) nil)))
                        ((equal (returnFirstCharacter p) #\=)
                                    (let ()
                                            (if (and  (returnRestCharacters p) (null (val (returnRestCharacters p) a)))
                                                (match2 nil nil (cons (
                                                                                list  = (returnRestCharacters p)  d)  a)
                                                )
                                                (let ()
                                                    (if (and  (returnRestCharacters p) (equal (val (returnRestCharacters p) a) (car d))) 
                                                        (match2 (cdr p) (cdr d) a) nil)
                                                )
                                            )
                                    )
                        )
                    )
    )
    (   (listp p) 
                    (cond 
                        ((equal (list-length p) (list-length d))
                            (let ()
                            (   if (equal p d) 
                                    (match2 nil nil a)  
                                    (let ()
                                        (append (match2 (car p) (car d) a)(match2 (cdr p) (cdr d) a) )
                                    )


                            )
                            )
                        )
                    )
    )

)
)

我自己调用了match2两次。我希望递归调用发生。当match2的调用返回true或nil时 该计划终止 我希望将控制权传递回上一个调用它的match2。

如你所见,我已经两次调用match2。 (listp p)match2中的这个条件我需要做递归。如何做到这一点

1 个答案:

答案 0 :(得分:1)

这看起来像是COND块的一部分。考虑到这个假设,我已经重新添加了COND并重新格式化了代码,使其更加明显。

(cond ((alpha-char-p (returnFirstCharacter p))
       (let () (if (equal p d) (match2 nil nil a) nil)))
      ((equal (returnFirstCharacter p) #\=)
       (let ()
         (if (and (returnRestCharacters p)
                  (null (val (returnRestCharacters p) a)))
             (match2 nil nil (cons (list '= (returnRestCharacters p) d) a))
             (let ()
               (if (and (returnRestCharacters p) 
                        (equal (val (returnRestCharacters p) a)
                               (car d))) 
                   (match2 (cdr p) (cdr d) a) nil))))))

首先,你从尾部位置调用MATCH2,所以“将控制权交还给前一个match2”并不明显。一旦对MATCH2的调用发生,如所写的那样,返回值将简单地沿着调用链向上传播,因为你没有对返回值做任何事情。

其次,你没有明显的原因使用空的LET块(如果条件为真,第一个IF调用MATCH2,否则滑到下一个IF)。在这两种情况下,您都没有需要评估的多个表达式,因此您可以跳过LET块。此外,使用PROGN比使用空LET块更常规(对编译器无关紧要,但它对人类读者来说很重要)。

如果用MATCH2的整个函数定义替换上面的代码段并添加一个“普通英语”描述,你可能会有所帮助。

编辑:发布完整代码(并且格式错乱),MATCH2中只有一个案例是“返回并执行某些操作”的概念,这就是两个参数调用到APPEND,就在最后。至少有一段代码可能导致运行时错误(当然还有编译时警告),=用作变量(除非在其他地方有动态入口,可能应该是{ {1}})。

您仍未解释代码应该执行的操作。如果你坐下来写下你希望代码做的事情,一步一步地,你可能会找出你出错的地方。