글쎄, 단 하나 대신 둘 다 사용할 수있게되면 프로그래머는 범위를 엄격하게 제어 할 수 있습니다. let x = e1 in e2
의 경우, 바인딩은 e2
의 환경에만 존재하며, let rec x = e1 in e2
의 바인딩은 e1
과 e2
의 환경에 모두 존재합니다.
(편집 : 나는 것을 강조하고 싶다 하지 전혀 차이가없는 성능 문제.)
여기 가진이 비 재귀 바인딩 유용 두 가지 상황은 다음과 같습니다
기존 바인딩을 사용하는 상세 검색으로 기존 정의를 섀도 잉합니다. 뭔가 : let f x = (let x = sanitize x in ...)
, 여기서 sanitize
은 입력에 몇 가지 바람직한 속성이 있음을 보장하는 함수입니다 (예 : 정규화되지 않은 벡터 등의 표준을 취함). 이것은 어떤 경우에 매우 유용합니다.
매크로 프로그래밍과 같은 메타 프로그래밍. 어떤 표현식이든 에 대해 let x = foo in x * x
에있는 매크로 SQUARE(foo)
을 정의하고 싶다고 상상해보십시오. 출력에서 코드 중복을 피하기 위해이 바인딩이 필요합니다 (factorial n
을 두 번 계산하려면 SQUARE(factorial n)
필요 없음). let
바인딩이 반복적이지 않으면 위생적입니다. 그렇지 않으면 let x = 2 in SQUARE(x)
을 쓰고 올바른 결과를 얻을 수 없습니다.
따라서 필자는 실제로 재귀 적 바인딩과 비 재귀 적 바인딩을 모두 사용하는 것이 매우 중요하다고 주장합니다. 자, 기본적으로 let-binding의 동작은 관례입니다. let x = ...
은 재귀 적이며, 비 재귀 바인더를 얻으려면 let nonrec x = ...
을 사용해야한다고 말할 수 있습니다. 하나의 기본값 또는 다른 하나를 선택하는 것은 어떤 프로그래밍 스타일로 부탁하고 어떤 선택을해야하는지에 대한 좋은 이유가 있습니다. 하스켈은이 비 재귀 적 모드를 사용할 수 없기 때문에 ¹ 고통을 겪고 OCaml은 유형 수준에서 정확히 동일한 결함을 가지고 있습니다 : type foo = ...
은 재귀 적이며 사용할 수있는 재귀 적 옵션은 없습니다 - this blog post을 참조하십시오.
¹ : Google 코드 검색을 사용할 수있을 때이를 사용하여 Haskell 코드에서 let x' = sanitize x in ...
패턴을 검색했습니다. 이것은 재귀 적 바인딩을 사용할 수없는 경우의 일반적인 해결 방법이지만 나중에 실수로 x'
대신 x
을 쓰는 위험이 있으므로 안전하지 않습니다. 두 가지를 모두 사용하고자하는 경우가 있기 때문에 자발적으로 다른 이름을 사용할 수 있습니다 . 좋은 관용구는 unsanitized_x
과 같이 첫 번째 x
에 더 긴 변수 이름을 사용하는 것입니다. 어쨌든, 그냥 x'
을 찾고 (다른 변수 이름 없음) x1
은 많은 결과를 냈습니다. Erlang (그리고 가변 음영 처리를 어렵게 만드는 모든 언어 : Coffeescript 등)은 이런 종류의 더 심각한 문제를 가지고 있습니다.
즉, 기본적으로 (재귀 적이 아닌) 재귀 적 바인딩을 갖는 Haskell 바인딩을 선택하는 것은 기본적으로 지연 평가와 일치하므로 확실히 재귀 값을 만드는 것이 쉽습니다. 엄격한 기본 언어는 재귀 적 정의가 더 많은 제약을 갖습니다.
투표가 닫히는 이유는 무엇입니까? 합리적인 질문처럼 보입니다. – Sean
참조 @stackoverflow.com/questions/900585/why-are-functions-in-ocaml-f-not-recursive-by-default –
@Sean : 이것은 매우 자주 묻는 질문입니다. – Ashe