2010-04-04 5 views
8

며칠 전 Common Lisp을 배우기 시작했고, 트리에 숫자를 삽입하는 함수를 작성하려고합니다. 당신이 괄호 너무 많은 세트가있을 때 이런 일이 발생처럼 오류를 받고 있어요,Common lisp error : "람다 표현식이어야합니다"

주위에 인터넷 검색에서

*** - SYSTEM::%EXPAND-FORM: (CONS NIL LST) should be a lambda expression

, 그것은 보이지만, 주변 일을 한 시간 정도 동안보고 및 변경 한 후, 나는 '수 내가이 일을 할 수있는 곳을 알아 냈어.

(defun insert (lst probe) 
    (cond ((null lst) (cons probe lst)) 
     ((equal (length lst) 1) 
      (if (<= probe (first lst)) 
       (cons probe lst) 
       (append lst (list probe)))) 
     ((equal (length lst) 2) 
      ((cons nil lst) (append lst nil) (insertat nil lst 3) 
       (cond ((<= probe (second lst)) (insert (first lst) probe)) 
        ((> probe (fourth lst)) (insert (fifth lst) probe)) 
        (t (insert (third lst) probe))))))) 

나는 그것이 ((동일 (길이 LST 이후에 발생한 것 확신) 2), 아이디어는 기존에 빈리스트를 삽입하는 것입니다

은 무슨 일이 일어나고 코드입니다 목록, 다음 마지막에 빈 목록을 추가하고 중간에 빈리스트를 삽입

답변

6

맞음! 문제는 바로 그 다음 줄에 있습니다.

((cons nil lst) (append lst nil) (insertat nil lst 3) ... 

문제는 두 개의 여는 괄호입니다. 괄호는 특별한 문맥 (예 : cond 형식)에서 의미를 바꿀 수 있지만,이 문맥에서 괄호는 익숙한 것처럼 일반 함수 응용 프로그램을 의미합니다. 즉, 괄호 뒤에 오는 첫 번째 것은 함수 여야합니다. 바깥 쪽 괄호의 관점에서 보면 첫 번째 것은 (cons nil lst)이므로 함수가되어야합니다 (그렇지 않습니다).

cons 함수는 원하는대로 새 목록을 반환하지만 이전 목록은 변경하지 않으므로 괄호를 제거 할 수 없습니다. 올바르게 기능을 들여 경우

(setq lst (cons nil lst)) 
(setq lst (append lst nil)) 
(setq lst (insertat nil lst 3)) 
... 
+0

나는 당신이 옳다고 믿습니다. 단점은 실제로리스트를 수정하지 않는다는 것을 잊었습니다. –

1

을 자네 말이 맞아, "오류가 여기에있다"로 표시된 라인에서 구문 오류가있다 :.

(defun insert (lst probe) 
    (cond ((null lst) (cons probe lst)) 
     ((equal (length lst) 1) 
     (if (<= probe (first lst)) 
      (cons probe lst) 
      (append lst (list probe)))) 
     ((equal (length lst) 2) 
     (#|Error is here|# (cons nil lst) (append lst nil) (insertat nil lst 3) 
      (cond ((<= probe (second lst)) (insert (first lst) probe)) 
       ((> probe (fourth lst)) (insert (fifth lst) probe)) 
       (t (insert (third lst) probe))))))) 

컴파일러/인터프리터에게 양식은 함수가 아닌 "함수"(cons nil list)에 대한 함수 호출로 읽습니다. 컴파일러는 lambda되지 않습니다 "연산자"위치에있는 복합 양식의 사용에 대해 여기에 불평 (그 자리에서 받아 화합물 형태의 유일한 종류.) 내가 다시와

((cons nil lst)       #| <-- Form in operator position |# 
(append lst nil)      #| <-- First argument form |# 
(insertat nil lst 3)     #| <-- Second argument form |# 
(cond ((<= probe (second lst)) (insert (first lst) probe)) #| Third argument |# 
     ((> probe (fourth lst)) (insert (fifth lst) probe)) 
     (t (insert (third lst) probe)))) 

도움을 줄 표현을 공식화하지만, 여기서 성취하고자하는 것이 확실하지 않습니다.

7

, 당신은 CONS NIL LST 앞에 여분의 괄호가 있음을 볼 수 있습니다 당신은 아마 이런 식으로 뭔가를 할 수 있습니다.

(defun insert (lst probe) 
    (cond ((null lst) (cons probe lst)) 
     ((equal (length lst) 1) 
     (if (<= probe (first lst)) 
      (cons probe lst) 
      (append lst (list probe)))) 
     ((equal (length lst) 2) 
     ((cons nil lst) (append lst nil) (insertat nil lst 3) 
      (cond ((<= probe (second lst)) (insert (first lst) probe)) 
       ((> probe (fourth lst)) (insert (fifth lst) probe)) 
       (t (insert (third lst) probe))))))) 

대부분의 Lisp IDE에서 표현식을 들여 쓸 수 있습니다. LispWorks에서 전체 식을 선택하고 m-x Indent Region을 누릅니다.

0

즉각적인 오류를 수정하려면 그 전에 PROGN을 추가하기 만하면됩니다 (CONS NIL ...). PROGN은 각 양식을 평가하고 마지막 양식의 값을 값으로 반환하여 작동합니다.

그러나 프로그램은 여전히 ​​사용자가 생각하는대로 작동하지 않습니다 (그렇게 생각합니다). 여러분은 Common Lisp에서 첫 번째 cons 객체를 사용하여 비어 있지 않은리스트 전체를 표현할 수 있습니다. 단순히 head cons를 대체 할 수는 없습니다.더 좋은 방법은 새 목록을 함수의 값으로 반환하는 것입니다.

(defun insert (lst probe) 
    (ecase (length lst) 
    (0 (list probe)) 
    (1 (let ((c (first lst))) 
     (if (<= probe c) 
      (list probe c) 
      (list c probe)))) 
    (2 (cond 
     ((<= probe (first lst)) 
      (list probe (first lst) nil (second lst) nil)) 
     ((> probe (second lst)) 
      (list nil (first lst) nil (second lst) probe)) 
     (t 
      (list nil (first lst) probe (second lst) nil)))))) 

아마도이 기능을 사용하면 (setf lst (insert lst [some-number]))이됩니다.