2017-09-10 4 views
-1

私はLISPが新しく、クラスのcond文を作成しようとしています。現在、渡された値がリストであるかどうかを確認しようとしています。そうであれば、文字dをリストに追加します。ここでLISPリストが追加されず、2回印刷されています

は私のコードです:

(defun test(L) 
(listp L) 
(cond ((listp L) (append L (list 'd))) 
) 
(write L) 
) 
(test (list 'a 'b 'c)) 

私が手出力は次のようになります。

(A B C) 

(A B C) 

私がテストを変更する場合:(test (car(list 'a 'b 'c)))

私が手に新しい出力は次のようになります。

A 

A 

私が疑問に思う2つのこと

1.)最初のテストがリストを渡すと、なぜリストにDが追加されないのですか?

2.)なぜ2回印刷されていますか?私はLISP Worksを使用していますので、実際には最終値などの出力方法とは何かを考えています。

+1

あなたはコードFを固定してください可能性行うにはormatting? – sds

答えて

3

1.)同じ理由str + "d"は、JavaまたはPythonでstrを変更しません。それはあなたが使用しない新しいリストを作成します!

>>> str + "d" 
'abcd' 
>>> str 
'abc' 

クレイジー類似じゃないですか?

2.)CLでは、returnが最後に評価された式です。 REPLはすべてのトップレベル式の結果を端末に出力します。引数リストを変異する方法

>>> def test(): 
... x = 2 + 3 
... print x 
... return x 
... 
>>> test() 
5 
5 

更新

:Pythonはあまりにもこれを行います。簡単な答えはあなたの代わりに、引数の最後のペアを変異させる必要があるということです。

:あなたがバインドを変更する必要がある場合は

(defun test (l) 
    (assert (consp 1) (l) "l needs to be a non nil list. Got: ~a" l) 
    (nconc l (list 'd) 
    (write l))) 

(defparameter *test1* (list 1 2 3)) 
(defparameter *test1-copy* *test1*) 
(test *test1*)   ; ==> (1 2 3 d) (and prints (1 2 3 d)) 
*test1*     ; ==> (1 2 3 d) 
*test1-copy*    ; ==> (1 2 3 d) 
(eq *test1* *test1-copy*) ; ==> t 

(test '()) 
** error l needs to be a non nil list. Got: NIL 

(nconc l x)(setf (cdr (last l)) x)

を行い、その後、マクロを作成する必要があります

(defmacro testm (var) 
    (assert (symbolp var) (var) "List needs to be a variable binding. Got: ~a" var) 
    `(progn 
    (when (listp ,var) 
     (setf ,var (append ,var (list 'd))) 
    (write ,var)))) 

(macroexpand '(testm *test2*)) 
; ==> (progn 
;  (when (consp *test2*) 
;   (setf *test2* (append *test2* (list 'd)))) 
;  (write *test2*)) 

(defparameter *test2* (list 1 2 3)) 
(defparameter *test2-copy* *test2*) 
(testm *test2*)   ; ==> (1 2 3 d) (and prints (1 2 3 d)) 
*test2*     ; ==> (1 2 3 d) 
*test2-copy*    ; ==> (1 2 3) 
(eq *test2* *test2-copy*) ; ==> nil 

(defparameter *x* nil) 
(testm *x*)    ; ==> (d) (and prints (d)) 
*x*      ; ==> (d) 

(testm '(1)) 
** error List needs to be a variable binding. Got: '(1) 

慣用的な方法は、それ

(defun test (list) 
    (if (consp list) 
     (append list '(d)) 
     list)) 

(write (test '(1 2 3))) 
; ==> (1 2 3 d) (and prints (1 2 3 d)) 

(defparameter *test3* '(1 2 3)) 
(setf *test3* (test *test3*)) 
*test3* ; ==> (1 2 3 d) 
+0

Lを更新してLにする最も良い方法は何ですか? –

+1

@KyleJは突然変異の仕方や改良方法を更新しました。 – Sylwester

+0

大変ありがとうございます –

関連する問題