通过 If 语句 LISP 中断循环
Breaking From Loop Through If Statement LISP
我目前正在用 LISP 编写一个小程序,它将接受一个列表,并将其拆分如下:
(split '(1 2 3) returns-> ((1 2) (3))
(split '(1 2 3 4) returns-> ((1 2) (3 4))
我觉得我已经很接近并且已经写出了它的基本逻辑,我的问题是如果 if 语句的计算结果为 T,我必须执行 2 - 3 个动作。因此我一直收到错误
Error(s), warning(s):
*** - SYSTEM::%EXPAND-FORM: (PUSH (CAR LST) (CDR (LAST NEWLST))) should be a
lambda expression
当 if 语句的计算结果为真时,我需要将当前列表的头部添加到我的列表变量 newLst 的末尾,然后我需要获取当前列表的尾部并设置我的其他值列出变量 new2Lst 到那个。这样做之后,我需要跳出循环并将两个列表附加到彼此。这可能没有多大意义,抱歉,希望代码更有意义,请在下面找到它。预先感谢大家的帮助,我真的很感激它的每一点!
(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)
时,即。不是在宏、特殊形式中,...,a
应该是一个用参数 b
和 c
调用的函数。
这就是为什么你有那个特定的错误: (push ...)
indeed is not a function name or a lambda expression.
未定义变量
您正在对未绑定到已知变量的符号调用 setq
,至少在您的函数中是这样。大多数实现随后将赋值视为对符号 symbol-value
的赋值,即使未指定行为。您应该通过 let
绑定在您的函数中声明它们:
(let ((w (length list))
(... ...))
...)
顺便说一句,你在这个函数中计算了两次列表的长度,长度可以只计算一次,实际上你只需要知道列表是否有一个元素并且其cdr中没有列表:这是一个 constant-time 计算,不像 list-length
需要遍历整个列表。
变量名,大小写
注意变量的命名方式,请遵守 Lisp 约定,使用 hyphen-separated-words
而不是大小写混合。
我目前正在用 LISP 编写一个小程序,它将接受一个列表,并将其拆分如下:
(split '(1 2 3) returns-> ((1 2) (3))
(split '(1 2 3 4) returns-> ((1 2) (3 4))
我觉得我已经很接近并且已经写出了它的基本逻辑,我的问题是如果 if 语句的计算结果为 T,我必须执行 2 - 3 个动作。因此我一直收到错误
Error(s), warning(s): *** - SYSTEM::%EXPAND-FORM: (PUSH (CAR LST) (CDR (LAST NEWLST))) should be a lambda expression
当 if 语句的计算结果为真时,我需要将当前列表的头部添加到我的列表变量 newLst 的末尾,然后我需要获取当前列表的尾部并设置我的其他值列出变量 new2Lst 到那个。这样做之后,我需要跳出循环并将两个列表附加到彼此。这可能没有多大意义,抱歉,希望代码更有意义,请在下面找到它。预先感谢大家的帮助,我真的很感激它的每一点!
(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)
时,即。不是在宏、特殊形式中,...,a
应该是一个用参数 b
和 c
调用的函数。
这就是为什么你有那个特定的错误: (push ...)
indeed is not a function name or a lambda expression.
未定义变量
您正在对未绑定到已知变量的符号调用 setq
,至少在您的函数中是这样。大多数实现随后将赋值视为对符号 symbol-value
的赋值,即使未指定行为。您应该通过 let
绑定在您的函数中声明它们:
(let ((w (length list))
(... ...))
...)
顺便说一句,你在这个函数中计算了两次列表的长度,长度可以只计算一次,实际上你只需要知道列表是否有一个元素并且其cdr中没有列表:这是一个 constant-time 计算,不像 list-length
需要遍历整个列表。
变量名,大小写
注意变量的命名方式,请遵守 Lisp 约定,使用 hyphen-separated-words
而不是大小写混合。