And*_*iro 2 lisp clisp sbcl common-lisp
我是普通Lisp的新手并且有一些挣扎.我正在研究给定x,y和一个数组的函数,如果(xy)有任何元素对角线,则垂直值的索引返回NIL.
(defun diagonal? (x y array)
(loop for line from 0 to 19 do
(let (col (aref array line)) (
(if (= col -1) (return-from diagonal? t))
(let (diag (= (abs (- x line)) (abs (- y col)))) (
if (= diag T) (return-from diagonal? NIL))
)
)))
return T
)
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试此功能时,我收到以下错误:
; caught ERROR:
; The LET binding spec (AREF ARRAY LINE) is malformed.
; (SB-INT:NAMED-LAMBDA DIAGONAL?
; (X Y ARRAY)
; (BLOCK DIAGONAL?
; (LOOP FOR LINE FROM 0 TO 19
; DO (LET (COL #)
; (# #)))
; RETURN
; T))
Run Code Online (Sandbox Code Playgroud)
Rai*_*wig 11
首先,非常重要:使用自动缩进.
(defun diagonal? (x y array)
(loop for line from 0 to 19 do
(let (col (aref array line)) (
(if (= col -1) (return-from diagonal? t))
(let (diag (= (abs (- x line)) (abs (- y col)))) (
if (= diag T) (return-from diagonal? NIL))
)
)))
return T
)
Run Code Online (Sandbox Code Playgroud)
然后你的代码用长行看起来很奇怪:永远不要把括号放在他们自己的行上,永远不要用开括号结束一行.
改进:
(defun diagonal? (x y array)
(loop for line from 0 to 19 do
(let (col (aref array line))
((if (= col -1)
(return-from diagonal? t))
(let (diag (= (abs (- x line))
(abs (- y col))))
(if (= diag T)
(return-from diagonal? NIL))))))
return T)
Run Code Online (Sandbox Code Playgroud)
第二:LET期望绑定列表.单个绑定是变量或(variable value):
(defun diagonal? (x y array)
(loop for line from 0 to 19 do
(let ((col (aref array line)))
((if (= col -1)
(return-from diagonal? t))
(let ((diag (= (abs (- x line))
(abs (- y col)))))
(if (= diag T)
(return-from diagonal? NIL))))))
return T)
Run Code Online (Sandbox Code Playgroud)
第三:LET希望有一个Lisp体.这是零个或多个Lisp形式:
(defun diagonal? (x y array)
(loop for line from 0 to 19 do
(let ((col (aref array line)))
(if (= col -1)
(return-from diagonal? t))
(let ((diag (= (abs (- x line))
(abs (- y col)))))
(if (= diag T)
(return-from diagonal? NIL)))))
return T)
Run Code Online (Sandbox Code Playgroud)
第四:=期望数字作为参数.T不是一个数字.=已经退货T或NIL我们可以测试.
(defun diagonal? (x y array)
(loop for line from 0 to 19 do
(let ((col (aref array line)))
(if (= col -1)
(return-from diagonal? t))
(if (= (abs (- x line))
(abs (- y col)))
(return-from diagonal? NIL))))
return T)
Run Code Online (Sandbox Code Playgroud)
第五:return T不是一个有效的Lisp形式.我们可以直接回来T.
(defun diagonal? (x y array)
(loop for line from 0 to 19 do
(let ((col (aref array line)))
(if (= col -1)
(return-from diagonal? t))
(if (= (abs (- x line))
(abs (- y col)))
(return-from diagonal? NIL))))
T)
Run Code Online (Sandbox Code Playgroud)
第六:我们不需要LET的col,我们可以用另一个替换它FOR的LOOP.
(defun diagonal? (x y array)
(loop for line from 0 to 19
for col = (aref array line)
do
(if (= col -1)
(return-from diagonal? t))
(if (= (abs (- x line))
(abs (- y col)))
(return-from diagonal? NIL))))
T)
Run Code Online (Sandbox Code Playgroud)
第七:多个IF可以写成单个COND.
(defun diagonal? (x y array)
(loop for line from 0 to 19
for col = (aref array line)
do (cond ((= col -1)
(return-from diagonal? t))
((= (abs (- x line))
(abs (- y col)))
(return-from diagonal? nil))))
t)
Run Code Online (Sandbox Code Playgroud)
Eigth:for from 0 to n可以用below (+ n 1)或替换upto n
(defun diagonal? (x y array)
(loop for line below 20
for col = (aref array line)
do (cond ((= col -1)
(return-from diagonal? t))
((= (abs (- x line))
(abs (- y col)))
(return-from diagonal? nil))))
t)
Run Code Online (Sandbox Code Playgroud)
第九:自从默认(RETURN-FROM ... T)返回T显式返回的函数返回后,我们可以用UNTIL循环中的子句替换它:
(defun diagonal? (x y array)
(loop for line below 20
for col = (aref array line)
until (= col -1)
when (= (abs (- x line))
(abs (- y col)))
do (return-from diagonal? nil))
t)
Run Code Online (Sandbox Code Playgroud)
第十:因为col只是迭代数组的值:
(defun diagonal? (x y array)
(loop for line below 20
for col across array
until (= col -1)
when (= (abs (- x line))
(abs (- y col)))
do (return-from diagonal? nil))
t)
Run Code Online (Sandbox Code Playgroud)
第十一:@Coredump的建议,使用NEVER.的默认返回值LOOP是现在T.nil当never子句失败时才返回.
(defun diagonal? (x y array)
(loop for line below 20
for col across array
until (= col -1)
never (= (abs (- x line))
(abs (- y col)))))
Run Code Online (Sandbox Code Playgroud)
根据CLHS, a let具有以下结构:
(let (var (var2 expression))
body ...)
Run Code Online (Sandbox Code Playgroud)
这里第一个绑定没有值,但它与写入相同:
(let ((var nil) (var2 expression))
body ...)
Run Code Online (Sandbox Code Playgroud)
您的绑定看起来像这样:
(let (col ; col initialized to nil OK
(aref array line)) ; variable aref initialized to?
...)
Run Code Online (Sandbox Code Playgroud)
您的变量aref应该只有一个表达式.事实上,你似乎缺乏一套parentesis使它看起来有点像Clojure.也许应该是:
(let ((col (aref array line)))
...)
Run Code Online (Sandbox Code Playgroud)
另外我注意到你有一个(在同一条线上,好像你在做一个块.这((if ....))是行不通的,因为它不是有效的Common Lisp代码.您会得到运算符应该是命名函数或lambda的错误.let是一个块,所以开始(let ...)创建一个块,这样你就可以在没有额外括号的情况下拥有多个表达式.
| 归档时间: |
|
| 查看次数: |
306 次 |
| 最近记录: |