2016-06-13 18 views
1

(f(car l))への二重再帰呼び出しを、set/setq/setfを使わずにどうして防ぐことができますか?Lisp:再帰関数の二重呼び出しの防止

(defun f(l) 
    (cond 
     ((null l) nil) 
     ((listp (car l)) (append (f (car l)) (f (cdr l)) (car (f (car l))))) 
     (T (list (car l))) 
    ) 
) 

次のように考えていますか?

(defun f(l) 
    (cond 
    ((null l) nil) 
    ((listp (car l)) 
     (funcall #'(lambda(ff) (append ff (f (cdr l)) (list (car ff)))) (f (car l)))) 
    (T (list (car l))) 
    ) 
) 
+0

これは、あなたの質問に直接関連はありませんが、私はこの機能を行うことになっているものを得ることはありません。あなたは少し説明できますか? – coredump

+0

あなたはただそれをチェックしなければなりません。それは運動です...これがすべてです。 set/setq/setfを使用せずに(f(car l)への2回目の再帰呼び出しを避けてください。 – esbej

+0

私はコード(http://pastebin.com/raw/N0Aj8Qsq)をリファクタリングしました。私は追加が適切なリストで動作することを期待しています。そのためにアサーションを追加しました。この機能は、NILの縮退したケースで機能します。しかし、再帰の基底が 'head'を非リストとする'(list head) 'なので、最初の要素が空でないリストであるように決して'(foo head) 'を構築することはありません。最後の句の本文を '(list(list head))'に置き換えると、適切なリストが入力として与えられたときに関数が何かを返すようになります。私はこれがおそらくこの演習では重要でないと認識しています。 – coredump

答えて

4

あなたの試みは大丈夫ですが、通常のように書かれている:

... 
(bar (foo abcde)) 
... 
(baz (foo abcde)) 
... 

- も注意>

(let ((r (foo abcde))) 
    ... 
    (bar r) 
    ... 
    (baz r) 
    ...) 

(funcall #'(lambda (foo) ...) bar) 
は、Common Lispで書くことができ として:

すでに述べたように
((lambda (foo) ...) bar) 

又は好ましい、と:

(let ((foo bar)) 
    ...) 
+0

これをクリアしてくれてありがとう!私はまだCLispで習慣を持っていないので、コードをきれいにしてくれてありがとう! – esbej

関連する問題