2017-02-07 1 views
0

이것은 내 lisp 코드입니다.Lisp - if 문 다양한 액션

(DEFUN F (A B) 
       (SETF C (* 4 A)) 
       (SETF D (* 2 (EXPT B 3))) 
       (SETF RES (+ C D)) 
       (IF (AND (TYPEP A 'INTEGER) (TYPEP B 'INTEGER)) 
        (list 'Final 'value '= res) 
       '(YOUR INPUTS ARE NOT NUMBERS))) 

예를 들어, (f 5 9)이 잘 작동합니다. 그러나 (f 'w 'q) 다음과 같은 오류 메시지가 작동하지 않습니다

(ERROR TYPE-ERROR DATUM W EXPECTED-TYPE NUMBER FORMAT-CONTROL [email protected]< ~s' is not of the expected type ~s'~:@> FORMAT-ARGUMENTS (W NUMBER)) Error: W' is not of the expected type NUMBER'

나는 A가, B는 정수 계산 4A + 2B^3 인 경우 만들고 싶어.

아니요 하나 이상이 정수 인쇄 오류 메시지가 아니면.

위의 코드를 시도해 보겠습니다. 그러나 if 문을 사용하여이 오류 처리를 수행하려면 어떻게해야합니까?

답변

5

먼저 로컬 변수를 정의하려면 LET or LET*을 사용해야합니다.

(defun f (a b) 
    (let* ((c (* 4 a))   ; You need LET* instead of LET because 
     (d (* 2 (expt b 3))) ; RES depends on the previous variables. 
     (res (+ c d))) 
    (if (and (typep a 'integer) (typep b 'integer)) 
     (list 'final 'value '= res) 
     '(your inputs are not numbers)))) 

실제 문제는 인수가 정수인지 확인하기 전에 계산을 수행하고 있다는 것입니다. IF 안에 계산을 이동해야합니다.

그런 목록을 반환하는 것은 이상합니다. 사용자를 위해 결과를 출력하려는 ​​경우 메시지를 인쇄하고 실제 결과를 반환해야합니다.

(defun f (a b) 
    (if (and (integerp a) (integerp b)) 
     (let ((result (+ (* 4 a) 
         (* 2 (expt b 3))))) 
     (format t "Final value = ~a~%" result) 
     result)          ; Return RESULT or 
     (format t "Your inputs are not integers.~%"))) ; NIL from FORMAT. 

대부분의 경우 인수가 올바른 유형이 아닌 경우 오류를 표시해야합니다. 계산을 수행하는 함수의 출력 결과는 대개 잘못된 아이디어입니다.

(defun f (a b) 
    (check-type a integer "an integer") 
    (check-type b integer "an integer") 
    (+ (* 4 a) 
    (* 2 (expt b 3)))) 

(defun main (a b) 
    (handler-case 
     (format t "Final value = ~a~%" (f a b)) 
    ;; CHECK-TYPE signals a TYPE-ERROR if the type is not correct. 
    (type-error() (warn "Your inputs are not integers.")))) 

(main 12 1) 
; Final value = 50 
;=> NIL 
(main 12 'x) 
; WARNING: Your inputs are not integers. 
;=> NIL 

Common Lisp 조건 시스템을 사용하면 다시 시작을 사용하여 오류를 수정할 수 있습니다. CHECK-TYPESTORE-VALUE이라는 이름의 다시 시작을 설정하며,이 곳에서 올바른 값을 제공 할 수 있습니다. 이 경우 아마도 이해가되지 않지만, 기본값으로 1을 사용할 수 있습니다.

(defun main (a b) 
    (handler-bind ((type-error (lambda (e) 
           (store-value 1 e)))) 
    (format t "Final value = ~a~%" (f a b)))) 

(main 12 1) 
; Final value = 50 
;=> NIL 
(main 12 'x) 
; Final value = 50 
;=> NIL 

조건/오류 처리기가 당신이 그들을 사용하고 대신 함수를 호출하기 전에 인수를 확인하고 싶지 않을 수도 성능에 중요한 기능을 위해, 그래서 약간의 오버 헤드를 추가 할 공지있다.

(declaim (ftype (function (integer integer) integer) f)) 
(defun f (a b) 
    (declare (optimize (speed 3) (safety 0) (debug 0))) 
    (+ (* 4 a) 
    (* 2 (expt b 3)))) 

(defun main (a b) 
    (if (and (integerp a) 
      (integerp b)) 
     (format t "Final value = ~a~%" (f a b)) 
     (warn "Your inputs are not integers."))) 
+0

초보자의 입장에서 볼 때 많은 도움이되었습니다. 귀중한 재료를 바탕으로 더욱 성장할 것입니다. 고맙습니다. –