2010-07-09 5 views
14

는 최근 계획을 공부하고 다음과 같은 방법으로 정의되는 함수 건너 왔습니다 ? null로? 또는 지휘관이이하자 블록하지 않고 함수 정의에서 사용할 수있는 기능을 내장 할 때, CDR하는? 속도 최적화의는의 목적 (CDR, CDR) ((하자)

답변

30

일반 R5RS Scheme에는 모듈 시스템이 없습니다. 최상위 모듈 만 있습니다. 모든면에서 수정이 가능하므로 원하는 방식으로 언어를 "사용자 정의"할 수 있습니다. 그러나 모듈 시스템이 없으면 이것이 제대로 작동하지 않습니다. 예를 들어, 당신이로드 도서관에서

(define (sub1 x) (- x 1)) 

쓰기 - 그리고 지금 당신은 -을 다시 정의 할 수 있습니다 :

(define - +) ; either this 
(set! - +) ; or this 

을 지금 당신은 실수로 하나의 입력을 감소시키는 sub1에 의존 내 라이브러리 돌파 , 그리고 결과적으로 창문을 아래로 끌 때 창문이 올라가거나 뭐든간에.

이제
(define sub1 (let ((- -)) (lambda (x) (- x 1)))) 

이 일이 "더 잘 작동합니다 : 누군가를 변경하기 전에

여러 라이브러리에 의해 사용되는이 주변에있는 유일한 방법은,,, 빼기 기능의 관련 정의를"잡아 "하는 것입니다 "-을 변경하여 내 sub1 기능의 의미를 수정할 수 없으므로 (제외 ... 당신이 내 라이브러리를 ...로드 전에 당신이 그것을 수정하는 경우)이 결과로,

어쨌든 (그리고 당신이 - 라이브러리가로드 원래 하나라는 것을 알고있는 경우) 일부 컴파일러는이를 감지하여 - 호출이 항상 실제 빼기 함수가 될 것이므로 호출을 인라인으로 수행합니다 (-에 대한 호출을 인라이닝하면 결과적으로 두 숫자를 빼기위한 어셈블리 코드가 생성 될 수 있음). 큰 속도 향상). 그러나 위의 설명에서 말했듯이, 이것은 실제 이유와 우연히 더 일치합니다.

마지막으로, R6RS (그리고 그 전에 몇 가지 기법 구현)이 고정 및 라이브러리 시스템을 추가, 그래서이 트릭에 대한 사용도 없다했다 다음 sub1 코드가 라이브러리에 다른 코드만큼 안전에 -을 다시 정의되지는 어떤 식 으로든 컴파일러는이를 기반으로 안전하게 코드를 최적화 할 수 있습니다. 영리한 트릭이 필요 없습니다.

+0

철저한 답변을 부탁드립니다! – redwoolf

2

을. 지역 변수 접근은 일반적으로 빨리 전역 변수보다.

+0

자세히 설명 할 수 있습니까? let과 바인딩하는 과정은 검색과 마찬가지로 많은 시간이 소요될 것으로 보인다. – redwoolf

+0

@redwoolf : 'let'으로 바인딩 할 때의 조회는 한 번만 발생하지만,'cdr'은 함수에서 여러 번 사용 (조회) 될 수 있습니다. – Teddy

+3

일부 구현에서는 속도면에서 이점이 있지만,이 작업을 수행하는보다 중요한 이유는 단지 부산물 일뿐입니다. 저는 그것에 대해 별도의 대답으로 씁니다. –