[lambda] 람다는 무엇입니까?

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

C # 3.5 이상

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)

당신이 귀찮게 할 필요가 없다는 것을 제외하고 :

  1. 다른 곳에서 함수 선언하기 (나중에 코드를 다시 방문 할 때 찾아야 함)
  2. 한 번만 사용하는 이름을 지정하십시오.

값을 함수하는 데 익숙해지면 값없이 수행 해야하는 것은 다음과 같이 모든 표현식의 이름을 지정하는 것만 큼 바보처럼 보입니다.

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를 사용합니다.


추가 : http://imgur.com/a/XBHub

람다


답변

약간 지나치게 단순화 됨 : 람다 함수는 다른 함수로 전달 될 수 있으며 논리 액세스됩니다.

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는 코드 (함수)를 데이터로 처리하는 방법입니다.