문제는 함수 인코딩 측면에서 실제로 많은 여유가 없다는 것입니다. 주요 옵션은 다음과 같습니다.
용어 재 작성 : 함수를 추상 구문 트리 (또는 그 일부 인코딩)로 저장합니다. 함수를 호출 할 때 구문 트리를 수동으로 이동하여 매개 변수를 인수로 대체합니다. .
클로저 : 함수를 표현하는 방법, 구문 트리, 기계 코드 일 가능성이 있습니다. 그리고이 함수들에서, 당신은 어떤 식 으로든 당신의 주장을 참조로 참조합니다. 포인터 오프셋 일 수 있고 정수 또는 De Bruijn 색인 일 수 있으며 이름 일 수 있습니다. 그런 다음 함수를 클로저 로 표시합니다. 함수의 모든 자유 변수를 포함하는 데이터 구조와 쌍을 이루는 함수 "명령"(트리, 코드 등)입니다. 함수가 실제로 적용되면 어떻게 든 환경, 포인터 산술 등을 사용하여 데이터 구조에서 자유 변수를 찾는 방법을 알 수 있습니다.
다른 옵션이 있다고 확신하지만 이것이 기본 옵션이며 거의 모든 다른 옵션이 기본 폐쇄 구조의 변형 또는 최적화가 될 것으로 생각합니다.
따라서 성능 측면에서 클로저는 용어 재 작성보다 거의 보편적으로 성능이 우수합니다. 변형 중 어떤 것이 더 낫습니까? 그것은 당신의 언어와 아키텍처에 크게 의존하지만 "무료 변수를 포함하는 구조체가있는 기계 코드"가 가장 효율적이라고 생각합니다. 그것은 함수가 필요로하는 모든 것 (지시와 값)을 가지고 있으며, 더 이상 아무것도 호출하지 않으며, 장기 호출을 끝내지 않습니다.
현재 인코딩 알고리즘의 인기있는 기능 언어 (Haskell, ML) 사용에 관심이 있습니다.
나는 전문가는 아니지만 99 %의 ML 맛이 있지만 일부 최적화는 가능하지만 설명하는 클로저의 변형을 사용합니다. (아마도 구식 일 수도 있음) 관점에 대해서는 이 내용을 참조하십시오 .
Haskell은 게으른 평가로 인해 조금 더 복잡한 작업을 수행합니다. Spineless Tagless Graph Rewriting을 사용 합니다.
또한 가장 효율적인 방법으로 달성 할 수 있습니다.
가장 효율적인 것은 무엇입니까? 모든 입력에서 가장 효율적인 구현은 없으므로 평균적으로 효율적인 구현을 얻을 수 있지만 각각 다른 시나리오에서 우수합니다. 따라서 가장 효율적이거나 가장 효율이 낮은 명확한 순위는 없습니다.
여기 마법이 없습니다. 함수를 저장하려면 자유 값을 어떻게 든 저장 해야 합니다. 그렇지 않으면 함수 자체보다 적은 정보를 인코딩합니다. 부분 평가를 통해 일부 무료 값을 최적화 할 수 있지만 성능이 위험 할 수 있으므로 항상 중지되도록주의해야합니다.
공간 효율성을 얻기 위해 일종의 압축 또는 영리한 알고리즘을 사용할 수 있습니다. 그러나 당신은 우주를 위해 거래하는 시간이거나 어떤 경우에 최적화되어 있고 다른 경우에는 느려지는 상황에 처해 있습니다.
일반적인 경우는 최적화 할 수 있지만 일반적인 경우 는 언어, 응용 프로그램 영역 등에서 변경 될 수 있습니다. 비디오 게임에 빠른 코드 유형 (숫자 크 런칭, 큰 입력의 타이트한 루프)은 아마도 컴파일러 (트리 탐색, 작업 목록 등)의 빠른 속도
보너스 포인트 : 함수 인코딩 된 정수를 네이티브 정수 (C의 short, int 등)에 매핑하는 인코딩이 있습니까? 가능합니까?
아니요, 불가능합니다. 문제는 람다 미적분이 용어를 내성적으로 만들 수 없다는 것입니다. 함수가 Church-numeral과 동일한 유형의 인수를 사용하는 경우 해당 숫자의 정확한 정의를 검사하지 않고 함수를 호출 할 수 있어야합니다. 이것이 교회 인코딩의 일입니다. 당신이 그들과 함께 할 수 있는 유일한 것은 그것들을 부르는 것입니다. 그리고 당신은 이것으로 유용한 모든 것을 시뮬레이션 할 수 있지만 비용이 없습니다.
더 중요한 것은 정수는 가능한 모든 이진 인코딩을 차지한다는 것입니다. 따라서 람다가 정수로 표시되면 교회 수가 아닌 람다를 나타낼 방법이 없습니다! 또는 람다가 숫자인지 여부를 나타내는 플래그를 소개하지만 원하는 효율성은 아마도 창 밖으로 나옵니다.
편집 : 이것을 작성 한 후, 고기능 함수를 구현하기위한 세 번째 옵션 인 defunctionalization을 알게되었습니다 . 여기서는 함수 switch
로 제공된 람다 추상화에 따라 모든 함수 호출이 큰 문장 으로 바뀝니다 . 여기서의 단점은 전체 프로그램 변환이라는 것입니다. 사전에 완전한 람다 추상화 세트가 필요하기 때문에 부분을 개별적으로 컴파일 한 다음이 방식으로 연결할 수 없습니다.