我目前正在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
当你想计算一系列表达式a
、b
、c
时,你需要把它们放在(progn a b c)
的形式中。但这里你把它们包装在一个形式列表中:当你在正常的计算上下文中计算(a b c)
时,即不是在宏、特殊形式…中。。。,CCD_ 7被期望为使用参数b
和c
被调用的函数。这就是为什么会出现特定错误的原因:(push ...)
实际上不是函数名或lambda表达式。
未定义的变量
您正在对未绑定到已知变量的符号调用setq
,至少在函数中是这样。大多数实现将该分配视为对符号的symbol-value
的分配,即使行为未指定。您应该通过let
绑定在函数中声明它们:
(let ((w (length list))
(... ...))
...)
顺便说一句,在这个函数中,你计算了两次列表的长度,长度只能计算一次,事实上,你只需要知道列表的cdr中是否有一个元素而没有列表:这是一个恒定的时间计算,而list-length
需要遍历整个列表。
变量名,大小写
请注意如何命名变量,并使用hyphen-separated-words
而不是混合使用大小写,以遵守Lisp约定。