在这个例子中,Lisp“prog”是如何工作的?

时间:2013-01-13 14:22:35

标签: lisp common-lisp

我是lisp的初学者,我需要有人向我解释一下prog形式是如何运作的。 l1的初始值是多少?没??

如果列表在第一级有偶数个元素,问题输出T,否则为零。

(defun nr_par (l)
  (prog ((l1 l))
    ciclu
    (cond
      ((null l1) (return T))
      ((null (cdr l1)) (return NIL))
      ((null (cddr l1)) (return T))
      (T (setf l1 (cddr l1))
         (go ciclu)))))

在控制台上:

(nr_par '(1 2 3 4 5 6 7 8))

T

3 个答案:

答案 0 :(得分:6)

该程序很简单,但不是非常惯用的lisp(它是相当必要的而不是功能性的)。一步一步如下。

prog使用一系列变量绑定,在这种情况下,l1最初被赋予l的值。然后,循环开始的一系列语句(再次,不是非常lisp惯用)。

这种类型的循环再次使用标记(ciclu)和goto指令(go),不推荐,但它就在那里。之后,cond检查一系列案例。当列表为空(null)时,返回true,在其他情况下,检查长度是偶数还是奇数,并返回值。

如果列表长于一个或两个元素(两个案例都不为null),则调整l1列表以指向其自身的下一个元素({{1}功能)。

最后,cddr函数会将程序恢复为go标记。

当符合任何ciclu条款时,该程序将结束,返回condT

答案 1 :(得分:2)

请参阅PROG in CLHSL1 var L init-form ,因此{{1}的初始值}}是L1的值。

答案 2 :(得分:1)

正如the CLHS page for prog所说,它做了三件事:让你拥有本地变量并初始化它们;允许您拥有tagbody中的标记并使用go;并允许您在名为return的{​​{1}}内使用block

NIL

函数调用毕竟是一个美化的(defun nr_par (l) (prog ((l1 l)) ; local binding(s) ciclu (if (null l1) (return T)) ; return (if (null (cdr l1)) (return NIL)) (setf l1 (cddr l1)) (go ciclu))) ; go (defun nr_par1 (l) ; directly equivalent (labels ((ciclu (l1) (if (null l1) (return-from ciclu T)) (if (null (cdr l1)) (return-from ciclu NIL)) (ciclu (cddr l1)))) (ciclu l))) (defun nr_par2 (l) ; also equivalent (do ((l1 l (cddr l1))) (NIL) ; while T ... (cond ((null l1) (return T)) ((null (cdr l1)) (return NIL))))) ,不是吗?

另请参阅Longest decreasing sequence in Lisp以获取一个示例,该示例表示使用一堆goto语句手动编译为prog的几个相互递归函数。