comp-sci 배경이없는 사람의 경우 Computer Science 세계에서 람다는 무엇입니까?
답변
Lambda는 Lambda Calculus 에서 제공 되며 프로그래밍에서 익명 함수를 나타냅니다.
이것이 왜 시원합니까? 이름을 지정하지 않고 빠른 처리 기능을 작성할 수 있습니다. 또한 클로저를 작성하는 좋은 방법을 제공합니다. 그 힘으로 이런 일을 할 수 있습니다.
파이썬
def adder(x):
return lambda y: x + y
add5 = adder(5)
add5(1)
6
파이썬 스 니펫에서 알 수 있듯이 함수 adder는 인수 x를 취하고 다른 인수 y를 취하는 익명 함수 또는 람다를 반환합니다. 이 익명 함수를 사용하면 함수에서 함수를 만들 수 있습니다. 이것은 간단한 예이지만 람다와 클로저의 힘을 전달해야합니다.
다른 언어의 예
펄 5
sub adder {
my ($x) = @_;
return sub {
my ($y) = @_;
$x + $y
}
}
my $add5 = adder(5);
print &$add5(1) == 6 ? "ok\n" : "not ok\n";
자바 스크립트
var adder = function (x) {
return function (y) {
return x + y;
};
};
add5 = adder(5);
add5(1) == 6
자바 스크립트 (ES6)
const adder = x => y => x + y;
add5 = adder(5);
add5(1) == 6
계획
(define adder
(lambda (x)
(lambda (y)
(+ x y))))
(define add5
(adder 5))
(add5 1)
6
Func<int, Func<int, int>> adder =
(int x) => (int y) => x + y; // `int` declarations optional
Func<int, int> add5 = adder(5);
var add6 = adder(6); // Using implicit typing
Debug.Assert(add5(1) == 6);
Debug.Assert(add6(-1) == 5);
// Closure example
int yEnclosed = 1;
Func<int, int> addWithClosure =
(x) => x + yEnclosed;
Debug.Assert(addWithClosure(2) == 3);
빠른
func adder(x: Int) -> (Int) -> Int{
return { y in x + y }
}
let add5 = adder(5)
add5(1)
6
PHP
$a = 1;
$b = 2;
$lambda = fn () => $a + $b;
echo $lambda();
하스켈
(\x y -> x + y)
자바이 게시물을 참조하십시오
// The following is an example of Predicate :
// a functional interface that takes an argument
// and returns a boolean primitive type.
Predicate<Integer> pred = x -> x % 2 == 0; // Tests if the parameter is even.
boolean result = pred.test(4); // true
루아
adder = function(x)
return function(y)
return x + y
end
end
add5 = adder(5)
add5(1) == 6 -- true
코 틀린
val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true
루비
루비는 함수를 호출하는 것과 동일한 구문을 사용하여 람다를 호출 할 수는 없지만 람다가 있다는 점에서 약간 다릅니다.
def adder(x)
lambda { |y| x + y }
end
add5 = adder(5)
add5[1] == 6
루비는 루비이기 때문에 람다의 축약 형 adder
이 있으므로 다음과 같이 정의 할 수 있습니다 .
def adder(x)
-> y { x + y }
end
아르 자형
adder <- function(x) {
function(y) x + y
}
add5 <- adder(5)
add5(1)
#> [1] 6
답변
람다는 인라인으로 정의 된 함수 유형입니다. 람다와 함께 일반적으로 함수, 람다 또는 기타에 대한 참조를 보유 할 수있는 일종의 변수 유형이 있습니다.
예를 들어 람다를 사용하지 않는 C # 코드는 다음과 같습니다.
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
public Int32 Sub(Int32 a, Int32 b)
{
return a - b;
}
public delegate Int32 Op(Int32 a, Int32 b);
public void Calculator(Int32 a, Int32 b, Op op)
{
Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}
public void Test()
{
Calculator(10, 23, Add);
Calculator(10, 23, Sub);
}
이것은 계산기를 호출하여 두 숫자뿐만 아니라 계산기 내부에서 호출하여 계산 결과를 얻는 방법을 전달합니다.
C # 2.0에는 위의 코드를 단축하는 익명 메소드가 있습니다.
public delegate Int32 Op(Int32 a, Int32 b);
public void Calculator(Int32 a, Int32 b, Op op)
{
Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}
public void Test()
{
Calculator(10, 23, delegate(Int32 a, Int32 b)
{
return a + b;
});
Calculator(10, 23, delegate(Int32 a, Int32 b)
{
return a - b;
});
}
그리고 C # 3.0에서 코드를 더 짧게 만드는 람다를 얻었습니다.
public delegate Int32 Op(Int32 a, Int32 b);
public void Calculator(Int32 a, Int32 b, Op op)
{
Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}
public void Test()
{
Calculator(10, 23, (a, b) => a + b);
Calculator(10, 23, (a, b) => a - b);
}
답변
“lambda”라는 이름은 역사적인 유물 일뿐입니다. 우리가 말하는 것은 그 값이 함수 인 표현식입니다.
간단한 예 (다음 줄에 Scala 사용)는 다음과 같습니다.
args.foreach(arg => println(arg))
여기서 foreach
메소드에 대한 인수 는 익명 함수에 대한 표현식입니다. 위의 줄은 다음과 같이 작성하는 것과 거의 같습니다 (실제 코드는 아니지만 아이디어를 얻습니다).
void printThat(Object that) {
println(that)
}
...
args.foreach(printThat)
당신이 귀찮게 할 필요가 없다는 것을 제외하고 :
- 다른 곳에서 함수 선언하기 (나중에 코드를 다시 방문 할 때 찾아야 함)
- 한 번만 사용하는 이름을 지정하십시오.
값을 함수하는 데 익숙해지면 값없이 수행 해야하는 것은 다음과 같이 모든 표현식의 이름을 지정하는 것만 큼 바보처럼 보입니다.
int tempVar = 2 * a + b
...
println(tempVar)
필요한 곳에 표현식을 작성하는 대신 :
println(2 * a + b)
정확한 표기법은 언어마다 다릅니다. 그리스어가 항상 필요한 것은 아닙니다! 😉
답변
람다 식을 가진 공식 시스템 인 람다 미적분학 (lambda calculus )을 참조합니다. 이 함수는 유일한 인수에 대한 함수를 가져와 함수를 반환하는 함수를 나타냅니다. 람다 미적분학의 모든 함수는 그 유형 λ : λ → λ
입니다.
Lisp는 람다 개념을 사용하여 익명 함수 리터럴의 이름을 지정했습니다. 이 람다는 x와 y라는 두 개의 인수를 사용하여 제품을 반환하는 함수를 나타냅니다.
(lambda (x y) (* x y))
다음과 같이 인라인으로 적용 할 수 있습니다 ( 50으로 평가 ).
((lambda (x y) (* x y)) 5 10)
답변
람다 미적분학은 일관된 수학적 치환 이론입니다. 학교 수학에서 예를 x+y=5
들어와 짝을 이룬 것을 볼 수 x−y=1
있습니다. 교차 방정식 대체가 논리적으로 수행되는 경우 개별 방정식을 조작하는 방법과 함께이 두 정보를 함께 모을 수도 있습니다. Lambda 미적분은 이러한 대체를 수행하는 올바른 방법을 체계화합니다.
그것이 y = x−1
두 번째 방정식의 올바른 재 배열 인 것을 감안할 때 이것은 λ y = x−1
심볼의 심볼 x−1
을 대체하는 함수를 의미합니다 y
. 이제 λ y
첫 번째 방정식에서 각 항에 적용한다고 상상해보십시오 . 용어가 y
치환을 수행하는 경우 ; 그렇지 않으면 아무것도하지 마십시오. 종이에이 작업을 수행하면 어떻게 적용 λ y
하면 첫 번째 방정식을 해결할 수 있는지 알 수 있습니다.
그것은 컴퓨터 과학이나 프로그래밍이없는 해답입니다.
내가 생각할 수있는 가장 간단한 프로그래밍 예제는 http://en.wikipedia.org/wiki/Joy_(programming_language)#How_it_works 에서 온 것입니다 .
다음은 제곱 함수가 명령형 프로그래밍 언어 (C)로 정의되는 방법입니다.
int square(int x) { return x * x; }
변수 x는 함수가 호출 될 때 제곱 될 실제 값으로 대체되는 공식 매개 변수입니다. 기능적 언어 (Scheme)에서 동일한 기능이 정의됩니다.
(define square (lambda (x) (* x x)))
이것은 여러면에서 다르지만 여전히 동일한 방식으로 공식 매개 변수 x를 사용합니다.
답변
약간 지나치게 단순화 됨 : 람다 함수는 다른 함수로 전달 될 수 있으며 논리 액세스됩니다.
C #에서 람다 구문은 종종 익명 대리자와 같은 방식으로 간단한 메서드로 컴파일되지만, 세분화되고 논리를 읽을 수도 있습니다.
예를 들어 (C # 3에서) :
LinqToSqlContext.Where(
row => row.FieldName > 15 );
LinqToSql은 해당 함수 (x> 15)를 읽고 표현식 트리를 사용하여 실행하기 위해 실제 SQL로 변환 할 수 있습니다.
위의 진술은 다음과 같습니다.
select ... from [tablename]
where [FieldName] > 15 --this line was 'read' from the lambda function
이것은 읽을 수 없기 때문에 일반적인 메소드 또는 익명의 델리게이트 (컴파일러 마술)와 다릅니다 .
람다 구문을 사용하는 C #의 모든 메소드를 표현식 트리 (예 : 실제 람다 함수)로 컴파일 할 수있는 것은 아닙니다. 예를 들어 :
LinqToSqlContext.Where(
row => SomeComplexCheck( row.FieldName ) );
이제 표현식 트리를 읽을 수 없습니다. SomeComplexCheck를 분류 할 수 없습니다. SQL 문은 where없이 실행되며 데이터의 모든 행이 통과 SomeComplexCheck
됩니다.
Lambda 함수를 익명 메소드와 혼동해서는 안됩니다. 예를 들어 :
LinqToSqlContext.Where(
delegate ( DataRow row ) {
return row.FieldName > 15;
} );
이것은 또한 ‘인라인’함수를 가지고 있지만 이번에는 컴파일러 마술 일뿐입니다 .C # 컴파일러는 이것을 자동 생성 된 이름을 가진 새로운 인스턴스 메소드로 나눕니다.
익명 메소드는 읽을 수 없으므로 람다 함수에서와 같이 논리를 변환 할 수 없습니다.
답변
이 기사에서 Lambdas에 대한 설명을 좋아합니다. LINQ의 진화와 C #의 디자인에 미치는 영향 . Lambdas의 실제 세계를 보여주고 실용적인 모범으로 그것을 구축함에 따라 그것은 나에게 많은 의미가있었습니다.
빠른 설명 : Lambdas는 코드 (함수)를 데이터로 처리하는 방법입니다.