2010-02-18 2 views
3

나는 최근에 더 많은 Lisp 코드를 작성 해왔다. 특히 재귀 함수는 일부 데이터를 가져와 결과 데이터 구조를 만듭니다. 때로는 사용자가 제공 한 데이터 외에 함수의 다음 호출에 2 ~ 3 개의 정보를 전달해야하는 경우가 있습니다. 이러한 누적기를 호출 할 수 있습니다.함수에 누산기와 같은 매개 변수를 포함하는 최상의 방법은 무엇입니까?

이러한 코드를 내 코드로 구성하는 가장 좋은 방법은 무엇입니까?

(defun foo (user1 user2 &optional acc1 acc2 acc3) 
    ;; do something 
    (foo user1 user2 (cons x acc1) (cons y acc2) (cons z acc3))) 

이 내가하고 싶은대로 작동하지만, 난 정말 프로그래머에 & 선택적 매개 변수를 제시 할 필요가 없기 때문에 나는 걱정 :

현재, 나는 같은 것을 할 . 내가 어느 정도 고려하고

3 방법 :

  • 는 사용자가 그 즉시 확장 definiton를 호출하여 사용하는 것이 좋습니다되는 래퍼 함수가 있습니다.

  • labels은 내부적으로 서명이 간결한 함수 내에서 사용됩니다.

  • 그냥 루프와 변수를 사용하기 시작하십시오. 그러나, 나는 재귀 주위에 내 머리를 감싸고 싶다.

감사합니다!

답변

4

관용적 인 Common Lisp을 작성하려면 루프와 변수를 반복 할 것을 권장합니다. 재귀는 멋지지만 Common Lisper를위한 많은 도구 중 하나 일뿐입니다. 게다가 꼬리 끌기 제거는 Common Lisp 사양에 의해 보장되지 않습니다.

그런데 필자는 어쩔 때 구조가 나무 일 경우에는 labels 접근 방식을 권장합니다. 이는 필연적으로 반복적이며 어쨌든 꼬리 호출을 얻을 수 없습니다. 선택적 인수를 사용하면 구현 세부 사항이 호출자에게 유출됩니다.

+0

감사.나는 나무를 다루는 몇 가지 기능을 가지고 있었기 때문에 나는 그들을 '레이블'을 사용하도록 개조했다. 목록에서만 작동하는 또 다른 기능 세트이기 때문에 나는 그 기회를 사용하여'loop'에 익숙해졌습니다. –

2

사용자로부터 구현 세부 사항을 보호하려는 충동은 현명한 생각입니다. 나는 공통 리스프를 모르지만, Scheme에서는 공용 함수의 어휘 범위에서 헬퍼 함수를 ​​정의함으로써이를 수행한다.

(define (fibonacci n) 
    (let fib-accum ((a 0) 
        (b 1) 
        (n n)) 
    (if (< n 1) 
     a 
     (fib-accum b (+ a b) (- n 1))))) 

let 표현은 다음 함수를 호출, 함수를 정의하고하자 내에서만 볼 수의 이름에 바인드합니다.

+1

예, Common Lisp의 레이블은이 경우 Scheme의 'let'과 거의 동일하다고 생각합니다. – Ken

0

내가 언급 한 모든 옵션을 사용했습니다. 모두 장점이 있으므로 개인적인 취향에 따라 달라집니다.

내가 적절하다고 생각하는 것을 사용하여 도착했습니다. API에 &optional 축전기를 남겨 두는 것이 사용자에게 의미가 있다고 생각한다면 나는 그것을 남겨 둡니다. 예를 들어, reduce과 같은 함수에서 누적 기는 시작 값을 제공하기 위해 사용자가 사용할 수 있습니다. 그렇지 않으면, 나는 그것을 종종 깨닫게되면 loop, do 또는 iter (iterate 라이브러리에서) 형식으로 다시 작성합니다. 때로는 labels 도우미도 사용됩니다.