通过If语句LISP从循环中断



我目前正在LISP中编写一个小程序,该程序将接收一个列表,并将其拆分如下:

(split '(1 2 3) returns-> ((1 2) (3)) 
(split '(1 2 3 4) returns-> ((1 2) (3 4))

我觉得我已经非常接近了,并且已经写下了它的基本逻辑,我的问题是,如果if语句评估为T,我必须执行2-3个操作。因此,我一直收到错误

错误,警告:***-SYSTEM::%EXPAND-FORM:(PUSH(CAR LST((CDR(LAST NEWLST((应该是lambda表达式

当if语句的计算结果为true时,我需要将当前列表的头添加到我的列表变量newLst的末尾,然后我需要取当前列表的尾,并将我的另一个列表变量new2Lst的值设置为true。完成此操作后,我需要脱离循环,将两个列表相互附加。这可能没有多大意义,对不起,希望代码更有意义,请在下面找到它。提前感谢大家的帮助,我真的很感激每一点!

(defun split (lst) 
(cond ((= (list-length lst) 1) lst) 
(t   (setq w (list-length lst))
(setq newLst (list (car lst))) 
(setq new2Lst '())
(loop for x from 1 to (+ w 1) do 
(if (= x (ceiling (/ w 2))) 
( (push (car lst) (cdr( last newLst))) (setq new2Lst (cdr lst)) (return)) 
(push (car lst) (cdr( last newLst)))
)  
(setq lst (cdr lst))
) 
(append (list newLst) (list new2Lst))
) 
) 
)

progn

当你想计算一系列表达式abc时,你需要把它们放在(progn a b c)的形式中。但这里你把它们包装在一个形式列表中:当你在正常的计算上下文中计算(a b c)时,即不是在宏、特殊形式…中。。。,CCD_ 7被期望为使用参数bc被调用的函数。这就是为什么会出现特定错误的原因:(push ...)实际上不是函数名或lambda表达式。

未定义的变量

您正在对未绑定到已知变量的符号调用setq,至少在函数中是这样。大多数实现将该分配视为对符号的symbol-value的分配,即使行为未指定。您应该通过let绑定在函数中声明它们:

(let ((w (length list))
(... ...))
...)

顺便说一句,在这个函数中,你计算了两次列表的长度,长度只能计算一次,事实上,你只需要知道列表的cdr中是否有一个元素而没有列表:这是一个恒定的时间计算,而list-length需要遍历整个列表。

变量名,大小写

请注意如何命名变量,并使用hyphen-separated-words而不是混合使用大小写,以遵守Lisp约定。

最新更新