1

"고급 학생"언어 설정으로 라켓을 사용하고 있으며 함수를 사용하는 함수를 작성하는 데 어려움을 겪고 n 번 실행하고 시간을보고합니다. 각 실행에 대해 경과 된 시간. 이것은 내가 지금까지 가지고있는 것이다.함수를 매개 변수로 전달했지만 예기치 않은 결과가 발생합니다

(define (many n fn) 
    (cond 
    [(= n 0) true] 
    [else (many (sub1 n) (local ((define k (time fn))) k))])) 

숫자의 계승을 계산하는 fact이라는 함수가 있습니다. 내가 (time (fact 10000)) 평가하는 경우

(define (fact n) 
    (cond 
    [(= 0 n) 1] 
    [else (* n (fact (- n 1)))])) 

, 나는 CPU, 실제와 GC 시간에 대한 합리적인 결과뿐만 아니라 많은 수를 얻을. 모두 좋고 좋아. 내가 (many 3 (fact 10000))을 평가하려고 할 때

그러나, 내가 얻을 :

cpu time: 0 real time: 0 gc time: 0 
cpu time: 0 real time: 0 gc time: 0 
cpu time: 0 real time: 0 gc time: 0 
true 

왜 함수는 매개 변수로 전달에도 불구하고 fact 평가되지 않는 이유는 무엇입니까?

+0

함수를 전달하지 않고'()'내부에서 표현식을 평가 한 결과입니다. –

답변

5

many이 무엇인지 살펴 보겠습니다. 먼저 당신이 그것을 정의 :

(define (many n fn) 
    (cond 
    [(= n 0) true] 
    [else (many (sub1 n) 
       (local ((define k (time fn))) 
         k))])) 

를 다음 호출 : 모든 반복에 무슨 여기

> (many 3 (add1 41)) 
cpu time: 0 real time: 0 gc time: 0 
cpu time: 0 real time: 0 gc time: 0 
cpu time: 0 real time: 0 gc time: 0 
#t 
> 

을 때 many 통화 자신을 재귀 적 :

(define (many 3 42) 
    (cond 
    [(= 3 0) true] 
    [else (many (sub1 3) 
       (local ((define k (time 42))) 
         42))])) 

(define (many 2 42) 
    (cond 
    [(= 2 0) true] 
    [else (many (sub1 2) 
       (local ((define k (time 42))) 
         42))])) 

(define (many 1 42) 
    (cond 
    [(= 1 0) true] 
    [else (many (sub1 1) 
       (local ((define k (time 42))) 
         42))])) 

(define (many 0 42) 
    (cond 
    [(= 0 0) true] 
    [else (many (sub1 0) 
       (local ((define k (time 42))) 
         42))])) 

many 귀하의 정의는 재귀 적으로 자신을 호출 첫 번째 (time fn) 응용 프로그램의 결과 값이지만 정확한 시간 정보를 수집하지 않으므로 올바르지 않습니다. 프로 시저 응용 프로그램이 아니라 값 (우리의 경우 (add1 41) 값)이 아닙니다.

(define (many n fn) 
    (cond 
    [(= n 0) fn] 
    [else (many (sub1 n) 
       (local ((define k (time fn))) 
       k))])) 

을하고 다음을 얻을 것이다 : : 그냥 many의 당신의 정의에 fntrue 대체

> (many 3 (add1 41)) 
cpu time: 0 real time: 0 gc time: 0 
cpu time: 0 real time: 0 gc time: 0 
cpu time: 0 real time: 0 gc time: 0 
cpu time: 0 real time: 0 gc time: 0 
42 
> 

당신은 모든 재귀 호출에 fn42 동일 것을 알 수있다. 이는 많은 FP 언어가 모두 Applicative order 평가를 사용하고 에 대한 첫 번째 호출이 발생하기 전에 (add1 41)이 평가되기 때문에 발생합니다.

따라서 우리는 두 번째 인수 (fn가)의 많은에 전달됩니다 에게 기능을 (은 우리의 경우을 썽크) 보장하기 위해 lambda을 사용해야합니다.

(define (many n fn) 
    (time (fn)) 
    (if (= n 0) 
     true 
     (many (sub1 n) fn))) 

출력 예 :

> (many 3 (lambda() (fact 10000))) 
cpu time: 2734 real time: 2828 gc time: 1922 
cpu time: 906 real time: 953 gc time: 171 
cpu time: 891 real time: 953 gc time: 204 
cpu time: 938 real time: 984 gc time: 251 
#t 
> 

(fn) 상기 참조로서 기능 (lambda() (fact 10000) (썽크)의 결과인가를 수행 time 이미 반응식 함수 애플리케이션이 발현 주위 ()로 표현다시피 정확히 표현식을 전달하고 올바른 타이밍 정보를 표시합니다.

희망이 있습니다. 틀 렸으면 고쳐줘.

+0

+1 예쁜 답변 :) – leppie

+0

@ leppie : 고마워요! 나는 FP를 좋아합니다. 나는 공부하는 것이 격려가된다고 생각합니다. –

+0

안녕 Yasir, 응답 해 주셔서 감사합니다. 지금은 더 잘 이해하고 있으므로 평가 순서가 나를 트위프시킨 것 같습니다. 그러나 "중급"및 "고급"학생 설정에는 "if"기능이 없습니다. 따라서 원인을 이해하는 동안이 문제를 해결할 수 없습니다. 양해 해 주셔서 감사합니다. – Greenhorn

관련 문제