TL; DR 다른 사람들이 지적했듯이, 람다 표기법은 이름을 지정하지 않고 함수를 정의하는 방법 일뿐입니다.
긴 버전
이 주제에 대해 좀 더 자세히 설명하고 싶습니다. 면책 조항 : 나는 오래 전에 람다 미적분학 과정을 수강했습니다. 더 나은 지식을 가진 사람이 내 대답에 부정확 한 것을 발견하면, 그것을 향상시키는 데 도움을 주시기 바랍니다.
예를 들어 1 + 2
및 식으로 시작해 봅시다 x + 2
. 상수1
와 같은 리터럴 은 특정 고정 값에 바인딩되므로 상수2
라고 합니다.
변수 와 같은 식별자를 변수x
라고 하며이를 평가하려면 먼저 일부 값에 바인딩해야합니다. 그래서, 기본적으로는 평가할 수없는 당신이 모르는만큼 이다.x + 1
x
람다 표기법은 특정 입력 값을 변수에 바인딩하기위한 스키마를 제공합니다. 람다 식을 추가함으로써 형성 될 수있다 λx .
예를 들어, 기존의 발현 전면에 λx . x + 1
. 변수는 x
이라고합니다 무료 에서 x + 1
와 바인딩 에λx . x + 1
이것이 표현식 평가에 어떻게 도움이됩니까? 람다 식에 값을 입력하면
(λx . x + 1) 2
그런 다음 변수의 모든 발생을 x
값 2 로 대체 (바인딩)하여 전체 표현식을 평가할 수 있습니다 .
(λx . x + 1) 2
2 + 1
3
따라서 람다 표기법은 식 / 프로그램 블록에 나타나는 변수에 사물을 바인딩하는 일반적인 메커니즘을 제공합니다. 상황에 따라 프로그래밍 언어에서 크게 다른 개념을 만듭니다.
- Haskell과 같은 순전히 기능적인 언어에서 람다 식은 수학적인 의미로 함수 를 나타냅니다 . 입력 값이 람다의 본문에 주입되고 출력 값이 생성됩니다.
- 람다 식의 본문을 평가하는 많은 언어 (예 : JavaScript, Python, Scheme)에서 부작용이있을 수 있습니다. 이 경우 프로 시저 라는 용어를 사용 하여 차이 wrt 순수 함수를 표시 할 수 있습니다 .
차이점을 제외하고 람다 표기법은 형식 매개 변수를 정의하고 실제 매개 변수에 바인딩하는 것에 관한 것입니다.
다음 단계는 함수 / 프로 시저에 이름을 지정하는 것입니다. 여러 언어에서 함수는 다른 것과 같은 값이므로 함수에 다음과 같이 이름을 지정할 수 있습니다.
(define f (lambda (x) (+ x 1))) ;; Scheme
f = \x -> x + 1 -- Haskell
val f: (Int => Int) = x => x + 1 // Scala
var f = function(x) { return x + 1 } // JavaScript
f = lambda x: x + 1 # Python
Eli Barzilay가 지적했듯이 이러한 정의는 이름 f
을 값에 바인딩 하기 때문에 함수가됩니다. 따라서이 점에서 함수, 숫자, 문자열, 문자는 모두 같은 방식으로 이름에 바인딩 할 수있는 값입니다.
(define n 42) ;; Scheme
n = 42 -- Haskell
val n: Int = 42 // Scala
var n = 42 // JavaScript
n = 42 # Python
이러한 언어에서는보다 친숙하지만 동등한 표기법을 사용하여 함수를 이름에 바인딩 할 수도 있습니다.
(define (f x) (+ x 1)) ;; Scheme
f x = x + 1 -- Haskell
def f(x: Int): Int = x + 1 // Scala
function f(x) { return x + 1 } // JavaScript
def f(x): return x + 1 # Python
C와 같은 일부 언어는 (명명 된) 함수를 정의하기위한 후자의 표기법 만 지원합니다.
폐쇄
폐쇄 에 관한 최종 관찰 . 표현을 고려하십시오 x + y
. 여기에는 두 개의 자유 변수가 포함됩니다. x
람다 표기법을 사용하여 바인딩 하면 다음과 같은 결과가 나타납니다.
\x -> x + y
이것은 여전히 free 변수를 포함하고 있기 때문에 (아직) 함수가 아닙니다 y
. 바인딩 y
을 통해 함수를 만들 수도 있습니다.
\x -> \y -> x + y
또는
\x y -> x + y
+
기능 과 동일 합니다.
그러나 y
다른 방법으로 (*) 바인딩 할 수 있습니다 .
incrementBy y = \x -> x + y
함수 incrementalBy를 숫자에 적용한 결과는 클로저, 즉 바디 y
에 클로저가 정의 된 환경의 값에 바인딩 된 자유 변수 (예 :)가 포함 된 함수 / 프로 시저입니다 .
incrementBy 5
숫자를 5 씩 증가시키는 함수 (클로저)도 마찬가지 입니다.
노트 (*)
나는 여기에 약간의 바람을 피우고있다 :
incrementBy y = \x -> x + y
에 해당
incrementBy = \y -> \x -> x + y
바인딩 메커니즘은 동일합니다. 직관적으로 클로저는 더 복잡한 람다 식의 덩어리를 나타내는 것으로 생각합니다. 이 표현이 작성되면 모체 표현식의 일부 바인딩이 이미 설정되어 있으며 나중에 평가 / 호출 될 때 클로저가이를 사용합니다.