"하향 funargs"는 무엇입니까?
Jamie Zawinski 는 그의 (1997) 기사 "java sucks" 에서이 용어를 사용합니다 .
나는 하향식의 부족이 정말 싫다. 익명 클래스는 절름발이 대체물입니다. (저는 오래 지속되는 클로저없이 살 수 있지만 함수 포인터가 없다는 것은 큰 고통입니다.)
Lisper의 속어 인 것 같고 여기 에서 다음과 같은 간단한 정의를 찾을 수 있습니다 .하지만 어떻게 든 이해하지 못하는 것 같습니다.
많은 클로저는 그들이 참조하는 바인딩 범위 동안에 만 사용됩니다. 이들은 Lisp 용어로 "하향 funargs"로 알려져 있습니다.
Steve Yegge가 아니었다 면 지금은 어리석은 느낌이 들겠지만, 물어 보는 것은 괜찮은 것 같습니다.
Jamie Zawinski는 영웅입니다. 살아있는 전설. [...] "하향 funargs"라는 용어를 사용할 수있는 사람이 당신을 눈부시게하면서 그에게 설명을 요청하는 것뿐입니다.
저 같은 C 스타일 프로그래머를 위해 이것을 컴파일 할 수있는 Lisper가 여기 있습니까?
하향 funarg는 반환되지 않거나 선언 범위를 벗어나는 지역 함수입니다. 현재 범위에서 다른 함수 로만 아래쪽 으로 전달할 수 있습니다 .
두 가지 예. 이것은 하향 funarg입니다.
function () {
var a = 42;
var f = function () { return a + 1; }
foo(f); // `foo` is a function declared somewhere else.
}
이것은 아니지만 :
function () {
var a = 42;
var f = function () { return a + 1; }
return f;
}
이 용어의 출처를 더 잘 이해하려면 역사를 알아야합니다.
오래된 Lisp 해커가 일반적 으로 하향 funarg를 funarg 와 구별 할 수있는 이유 는 하향 funarg가 어휘 변수가없는 기존 Lisp에서 구현하기 쉽지만 일반적인 경우는 어렵 기 때문입니다.
전통적으로 로컬 변수는 가산함으로써 리스프 인터프리터 구현 결합 받는 (값 페어링 변수의 심볼 명 등) 환경 . 이러한 환경은 연관 목록을 사용하여 구현하기가 간단했습니다. 각 함수에는 고유 한 환경과 상위 함수의 환경에 대한 포인터가 있습니다. 변수 참조는 현재 환경을 조사하여 해결되었으며, 찾을 수없는 경우 상위 환경에서, 전역 환경에 도달 할 때까지 환경 스택에서 계속됩니다.
이러한 구현에서 지역 변수 는 동일한 이름의 전역 변수를 섀도 잉 합니다. 예를 들어, Emacs Lisp에서는 print-length
목록을 축약하기 전에 인쇄 할 최대 길이를 지정하는 전역 변수입니다. 함수 호출 주변에이 변수를 바인딩하면 해당 함수 내에서 print 문의 동작을 변경할 수 있습니다.
(defun foo () (print '(1 2 3 4 5 6))); 출력은 인쇄 길이 값에 따라 다릅니다. (foo); 인쇄 길이의 전역 값 사용 ==> (12 34 5 6) (let ((인쇄 길이 3)) (foo)); foo에 대한 호출 주위에 인쇄 길이를 로컬로 바인딩합니다. ==> (12 3 ...)
이러한 구현에서는 함수가 생성 될 때 함수의 환경에있는 변수가 평가 될 때 함수의 환경에 남아 있기 때문에 하향 funarg는 구현하기가 정말 쉽습니다.
이와 같이 작동하는 변수를 특수 또는 동적 변수 라고 하며 special
선언을 사용하여 Common Lisp에서 만들 수 있습니다 .
Common Lisp에서 :
(let ((a 3))
(mapcar (lambda (b) (+ a b))
(list 1 2 3 4)))
-> (4 5 6 7)
위의 형식에서 람다 함수는 DOWNWARD로 전달됩니다. 고차 함수 MAPCAR (함수와 값 목록을 인수로 가져온 다음 목록의 각 요소에 함수를 적용하고 결과 목록을 반환 함)에 의해 호출 될 때 람다 함수는 여전히 변수를 참조합니다. LET 표현식의 'a'. 그러나 그것은 모두 LET 표현 안에서 일어난다.
이 버전과 위의 비교 :
(mapcar (let ((a 3))
(lambda (b) (+ a b)))
(list 1 2 3 4))
여기서 람다 함수는 LET에서 반환됩니다. 조금 위로. 그런 다음 MAPCAR로 전달됩니다. MAPCAR가 람다 함수를 호출하면 주변 LET가 더 이상 실행되지 않습니다. 여전히 함수는 LET에서 변수 'a'를 참조해야합니다.
Funarg 문제 라는 Wiki에 대한 꽤 설명적인 기사가 있습니다.
"하향 funarg는 함수가 실제로 실행되지 않을 때의 함수 상태를 참조 할 수도 있습니다. 그러나 정의에 따라 하향 funarg의 존재는이를 생성하는 함수의 실행에 포함되기 때문에 함수의 활성화 레코드입니다. 일반적으로 스택에 저장할 수 있습니다. "
참조 URL : https://stackoverflow.com/questions/581182/what-are-downward-funargs
'programing tip' 카테고리의 다른 글
docker-compose 동일한 이미지에 대해 여러 인스턴스 생성 (0) | 2020.12.30 |
---|---|
Angular의 canLoad와 canActivate의 차이점은 무엇입니까? (0) | 2020.12.30 |
2 개의 열을 기반으로 SQL 고유 제약 조건을 생성하려면 어떻게해야합니까? (0) | 2020.12.30 |
Threaded Django 작업이 트랜잭션 또는 db 연결을 자동으로 처리하지 않습니까? (0) | 2020.12.30 |
이 응답에 대해 getOutputStream ()이 이미 호출되었습니다. (0) | 2020.12.30 |