2017-04-11 89 views
1

我正在使用Little Schemer,我試圖將所有答案轉換爲Common Lisp。 在第8章中,討論了匿名函數,並返回了匿名函數。 例如:通過匿名函數循環常見Lisp vs. Scheme

(define insertL-f 
    (lambda (test?) 
     (lambda (new old l) 
      (cond 
       ((null? l) (quote())) 
       ((test? (car l) old) (cons new l))) 
       (else (cons (car l) ((insertL-f test?) new old (cdr l)))))))) 

我的代碼:

(defun insertL-f (test) 
    (lambda (new old l) 
     (cond 
      ((null l) '()) 
      ((funcall test (car l) old) (cons new l)) 
      (t (cons (car l) (insertL-f test) new old (cdr l)))))) 

問題是代碼的第二塊的最後一行。我得到的錯誤是「cons的參數太多」,但我不能像Scheme代碼那樣添加一對額外的括號。這種風格的遞歸在Common Lisp中是不可能的嗎?

回答

2
(defun insertL-f (test) 
    (lambda (new old l) 
    (cond 
    ((null l) '()) 
    ((funcall test (car l) old) (cons new l)) 
    (t (cons (car l) 
       (funcall (insertL-f test) 
         new 
         old 
         (cdr l))))))) 
2

insertL-f返回功能,在您的計劃版本,應用它,而在CL具有扁平的列表,而不是如果與funcall應用它不過好像是要返回的功能等於它取了一個這樣你就可以通過與本地labels定義它緩存它:使用

(defun insert-l-f (test) 
    (labels ((func (new old l) 
      (cond 
       ((null l) '()) 
       ((funcall test (car l) old) (cons new l)) 
       (t (cons (car l) (func new old (cdr l))))))) 
    #'func)) 

方案相同的本地define(這確實是一個letrec與平坦的語法):

(define (insert-l-f test?) 
    (define (func new old l) 
    (cond 
     ((null? l) (quote())) 
     ((test? (car l) old) (cons new l))) 
     (else (cons (car l) (func new old (cdr l))))) 
    func)