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

标签 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 中的这个条件我需要做递归。怎么做

最佳答案

这看起来像是 COND block 的一部分。考虑到这个假设,我重新添加了 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 block (如果条件为真,则第一个 IF 调用 MATCH2,否则跳转到下一个 IF)。在这两种情况下,您都没有需要评估的多个表达式,因此您可以跳过 LET block 。此外,使用 PROGN 比使用空 LET block 更传统(对编译器无关紧要,但对人类读者来说很重要)。

如果您将上面的代码段替换为 MATCH2 的整个函数定义并添加您认为它应该做什么的“简单英语”描述,这可能会有所帮助。

编辑:随着整个代码的发布(以及糟糕的格式),MATCH2 中只有一种情况存在“返回并做某事”的概念,这就是作为参数的两个调用追加,就在最后。至少有一段代码可能会导致运行时错误(并且绝对是编译时警告),其中 = 用作变量(除非其他地方有动态索引,这可能是假设的为 '=).

您仍然没有解释代码应该做什么。如果您坐下来按部就类地编写您期望代码执行的操作,您可能会找出哪里出错了。

关于lisp - 如何从 lisp 中的函数返回控制权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3809602/

相关文章:

multithreading - 在 sbcl lisp 中使用线程时,变量在 lisp 中未绑定(bind)

iteration - SICP - 我对阶乘迭代过程的递归定义不好吗?

error-handling - 如何利用简单错误子类提供的格式控制

lisp - Lisp 文档模板中的星号是什么意思?

common-lisp - CLISP 错误消息 : an object cannot start with #\). 这是什么意思?

lisp - 检查 Tic-Tac-Toe 中的胜利

lisp - lisp 中的 CDR 使用

lisp - Common Lisp 中 let 定义的变量是否可变?

bash - 从 gimp xcf 文件中提取文本

lisp - 在 lisp 中乘以 2 个向量