2013-09-05 2 views
0

내 hw2를 쉽게 만들 수있는 자체 함수를 정의하려고하지만 작동하지 않습니다. 당신이 그것을보고 내가 무엇을 놓치고 있는지 말해 줄 수 있습니까?내 정의 된 cond 함수가 제대로 작동하지 않습니다 (LISP)

(DEFUN testAL(x) 
     COND ((ATOMP(x)) 'this-is-an-atom) 
      ((LISTP(x)) 'this-is-a-list) 
      (T 'this-is-neither)) 

이 조건부 함수가 입력 X를 가져 와서 원자, 목록 또는 둘 다 아닌 경우 출력하려고합니다. 문제는 NIL을 입력 할 때 오류가 발생한다는 것입니다. 언 바운드 변수 'COND'의 값을 사용하려고 시도합니다.

숙제 2가 다음과 같은 질문으로 구성

Which of the following are atoms, which lists, which both and witch neither?

a. nil

b. (expt 10 3)

c. (a b)

d. 64

e. T

f. (No place like home)

g. ‘(+ 3 5 6)

+0

hw2 란 무엇인가요? 어떻게하면 쉽게 할 수 있을까요? –

+0

@JoshuaTaylor 기술적으로 더 많은 작업이 될 것이지만 언어를 배우려고합니다. 위 질문에 hw2를 추가했습니다. – rtrigoso

답변

6

귀하의 괄호가 올바른 위치에 있지 않습니다. 괄호는 따옴표가 붙지 않는 한 함수 응용 프로그램의 시작입니다.

가변적 인 변수 cond으로 시작됩니다. 여는 괄호로 시작하지 않기 때문에 특별한 형식 인 (cond (predicate consequent) (predicate2 consequent2))이 아닙니다. 들여 쓰기에서

혼자 나는 당신이 쓰는 의미 생각 : 나는 x(x) 이후 수단의 주위에 여분의 괄호를 제거했다

(DEFUN testAL (x) 
    (COND ((ATOM x) 'this-is-an-atom) 
      ((LISTP x) 'this-is-a-list) 
      (T 'this-is-neither))) 

(testal 'test) ; ==> THIS-IS-AN-ATOM 
(testal '(a b c)) ; ==> THIS-IS-A-LIST 

x 변수 x을 의미하는 동안 기능 x을 적용합니다. x(+ x 3)과 같이 다른 위치에 적용하면 +이 적용될 함수이고 x이 피연산자 중 하나입니다.

atompatom으로 변경되었습니다. atom은 50 년대 최초의 LISP로 정의 된 최초 프리미티브 중 하나이기 때문에 대부분의 다른 술어와 마찬가지로 후위 p이 없습니다.

편집 : 여러 경기

당신은 가질 수있는 몇 가지 cond (또는 if 당신이 각 하나 개의 시험이 있기 때문에) 아무것도 아니 목록입니다 (트리거하지 않습니다 기지의 경우 이후 (print "THIS-IS-AN-ATOM") 같은 부작용을 CL의 원자도 아니다). 이것은 아마 이지스 솔루션 일 것입니다.

(DEFUN testAL (x) 
    (if (ATOM x) (print 'this-is-an-atom)) 
    (if (LISTP x) (print 'this-is-a-list))) 

(testal '()) ; ==> THIS-IS-A-LIST (but prints both) 

더 기능적인 접근을 위해서는 코드를 테스트 가능한 상태로 유지하고 부작용이있는 인쇄 기능을 제공하는 고차원 함수를 사용했습니다. 초보자에게 읽기에는 쉽지 않을 수 있습니다.

;; a list of pairs of predicate and their desription 
(defparameter *type-predicates-and-description* 
       '((douglasp . this-is-the-answer-to-everything) 
        (floatp . this-is-a-floating-pont-number) 
        (integerp . this-is-an-integer) 
        (numberp . this-is-a-number) 
        (null . this-is-null) 
        (listp . this-is-a-list) 
        (characterp . this-is-a-character) 
        (stringp . this-is-a-string))) 

;; custom made predicate 
(defun douglasp (x) 
    (and (numberp x) (= x 42))) 

;; returns all the types of a particular value 
(defun get-type-info (x) 
    "return a list if types thet describes argument" 
    (flet ((check-type (acc type-pair) 
      "Accumulate description when predicate match" 
      (if (funcall (car type-pair) x) 
       (cons (cdr type-pair) acc) 
       acc))) 
    ;; test x for each type predicate-description   
    (let ((res (reduce #'check-type 
         *type-predicates-and-description* 
         :initial-value '()))) 
     ;; check of empty list (no types matched) 
     (if (null res) 
      (list 'this-is-neither) 
     res)))) 

;; test it 
(get-type-info '()) ; ==> (THIS-IS-A-LIST THIS-IS-NULL) 
(get-type-info 42) ; ==> (THIS-IS-A-NUMBER 
        ;  THIS-IS-AN-INTEGER 
        ;  THIS-IS-THE-ANSWER-TO-EVERYTHING) 
(get-type-info #()) ; ==> (THIS-IS-NEITHER) 

;; Make a function to do side effects 
(defun print-type-info (x) 
    (format t "~{~a~^, ~}." (get-type-info x))) 

(print-type-info '()) ; ==> NIL 
         ; and prints "THIS-IS-A-LIST, THIS-IS-NULL." 
+0

내가 잘못 된 곳을 봅니다. 그것은 여분의 괄호로 잘 작동합니다. 후속 질문이 있습니다. COND는 java의 각 사례에서 "중단"하는 switch 문처럼 작동하는 것 같습니다. COND가 사실인지 아닌지에 관계없이 각 라인을 통과하여 각 라인을 인쇄하기를 바랬습니다. 예를 들어, 만약 내가 (testal 'NIL)했다면 "this-is-an-atom"과 "this-is-a-list"를 출력 할 것이지만, 아직 첫번째 T 조건에서 멈춘다. 제 질문은 : ** COND가 각 조건에 대해 X를 각 조건과 비교할 수있는 방법이 있습니까? ** – rtrigoso

+0

@rtrigoso 여러 답변과 관련하여 제 대답에 몇 가지 아이디어를 추가했습니다. – Sylwester

+0

여러 COND를 가지고 있거나이 경우 IF로 보았을 때 T는 대문자로 인쇄 출력을 건너 뛰지 않습니다. 감사합니다 – rtrigoso

관련 문제