我是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
答案 0 :(得分:6)
该程序很简单,但不是非常惯用的lisp(它是相当必要的而不是功能性的)。一步一步如下。
prog
使用一系列变量绑定,在这种情况下,l1
最初被赋予l
的值。然后,循环开始的一系列语句(再次,不是非常lisp惯用)。
这种类型的循环再次使用标记(ciclu
)和goto指令(go
),不推荐,但它就在那里。之后,cond
检查一系列案例。当列表为空(null
)时,返回true,在其他情况下,检查长度是偶数还是奇数,并返回值。
如果列表长于一个或两个元素(两个案例都不为null),则调整l1
列表以指向其自身的下一个元素({{1}功能)。
最后,cddr
函数会将程序恢复为go
标记。
当符合任何ciclu
条款时,该程序将结束,返回cond
或T
。
答案 1 :(得分:2)
请参阅PROG in CLHS:L1
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
的几个相互递归函数。