comp-sci 배경이없는 사람의 경우 Computer Science 세계에서 람다는 무엇입니까?
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);
}
Op
간단히 다음을 사용할 수도 있습니다.Func<int, int>
Console.WriteLine("Calculator: op " + op.Method.Name + " (" + a + ", " + b + ") = " + op(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는 코드 (함수)를 데이터로 처리하는 방법입니다.
@Brian 저는 C #, LINQ 및 비 LINQ 연산자에서 람다를 항상 사용합니다. 예:
string[] GetCustomerNames(IEnumerable<Customer> customers)
{ return customers.Select(c=>c.Name);
}
C # 이전에는 Ajax라는 용어가 만들어지기 전에 AJAX 함수에 대한 콜백을 위해 JavaScript에서 익명 함수를 사용했습니다.
getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});
그러나 C #의 람다 구문의 흥미로운 점은 자체적으로 유형을 유추 할 수 없다는 것입니다 (즉, var foo = (x, y) => x * y를 입력 할 수는 없지만 유형에 따라 다름) 에 할당되면 표현식을 나타내는 델리게이트 또는 추상 구문 트리로 컴파일됩니다 (LINQ 객체 매퍼가 "언어 통합"매직을 수행하는 방식).
LISP의 Lambdas는 인용 연산자로 전달 된 다음 목록 목록으로 순회 할 수도 있습니다. 강력한 매크로가 이런 식으로 만들어집니다.
질문은 공식적으로 크게 답변되었으므로 더 추가하지는 않겠습니다.
수학이나 프로그래밍에 대해 거의 또는 전혀 알지 못하는 사람에게 매우 간단하고 비공식적 인 말로, 나는 약간의 입력을 받고, 약간의 작업을 수행하고, 출력을 생성하고, 특정 이름이없는 작은 "기계"또는 "상자"라고 설명합니다. 그러나 우리는 그것이 어디에 있는지 알고 있으며이 지식만으로 그것을 사용합니다.
실제로 말해서, 함수가 무엇인지 아는 사람에게는 이름이없는 함수라고 말하고 일반적으로 그 메모리를 참조하여 사용할 수있는 메모리 포인트 (일반적으로 변수-함수 포인터의 개념에 대해 들었다면 비슷한 개념으로 사용합니다)-이 답변은 꽤 기본적인 사항 (클로저에 대한 언급은 없지만)을 다루지 만 쉽게 포인트를 얻을 수 있습니다.
익명 함수로 생각할 수 있습니다-여기에 더 많은 정보가 있습니다 : Wikipedia-Anonymous Function
C ++ 11 예제를 볼 수 없기 때문에 여기서 좋은 예제를 게시 하겠습니다 . 검색 한 후에는 내가 찾을 수있는 가장 명확한 언어 별 예입니다.
template<typename F>
void Eval( const F& f ) {
f();
}
void foo() {
Eval( []{ printf("Hello, Lambdas\n"); } );
}
void bar() {
auto f = []{ printf("Hello, Lambdas\n"); };
f();
}
매크로 대체와 ExecScript {} 및 Evaluate () 함수를 사용하는 Visual FoxPro에서 작업하기 때문에 람다 식으로 머리를 감싸는 데 문제가 있습니다.
? Calculator(10, 23, "a + b")
? Calculator(10, 23, "a - b");
FUNCTION Calculator(a, b, op)
RETURN Evaluate(op)
공식적인 람다를 사용하면 얻을 수있는 확실한 이점 중 하나는 컴파일 타임 검사입니다. Fox는 텍스트 문자열을 실행하려고 할 때까지 위의 텍스트를 오타인지 알지 못합니다.
이것은 데이터 중심 코드에도 유용합니다. 전체 루틴을 데이터베이스의 메모 필드에 저장 한 다음 런타임시 평가할 수 있습니다. 이를 통해 실제로 소스에 액세스하지 않고도 응용 프로그램의 일부를 조정할 수 있습니다. (그러나 그것은 또 다른 주제입니다.)
comp-sci 배경이없는 사람의 경우 Computer Science 세계에서 람다는 무엇입니까?
간단하고 읽을 수있는 파이썬 코드로 단계별로 직관적으로 설명합니다.
간단히 말해 람다는 익명의 인라인 함수일뿐입니다.
lambdas
기본적인 산술 배경을 가진 신입생으로 이해하기 위해 과제부터 시작합시다 .
과제의 청사진은 '이름 = 값'입니다.
In [1]: x = 1
...: y = 'value'
In [2]: x
Out[2]: 1
In [3]: y
Out[3]: 'value'
'x', 'y'는 이름이고 1, 'value'는 값입니다. 수학에서 함수를 시도하십시오
In [4]: m = n**2 + 2*n + 1
NameError: name 'n' is not defined
오류 보고서,
수학을 코드로 직접 작성할 수 없으며, 'n'을 정의하거나 값에 할당해야합니다.
In [8]: n = 3.14
In [9]: m = n**2 + 2*n + 1
In [10]: m
Out[10]: 17.1396
그것은 지금 작동합니다. 두 개의 seperarte 라인을 하나로 결합해야한다고 주장하십시오. 온다lambda
In [13]: j = lambda i: i**2 + 2*i + 1
In [14]: j
Out[14]: <function __main__.<lambda>>
오류가보고되지 않았습니다.
이것은 한 눈에 lambda
에 살펴보면 수학에서 컴퓨터로 직접 수행 할 때처럼 한 줄로 함수를 작성할 수 있습니다.
나중에 보자.
'할당'에 대해 더 깊이 파고 들자.
위에서 설명한 것처럼 등호 기호 =
는 단순 데이터 (1 및 '값') 유형 및 단순 표현식 (n ** 2 + 2 * n + 1)에 적용됩니다.
이 시도:
In [15]: x = print('This is a x')
This is a x
In [16]: x
In [17]: x = input('Enter a x: ')
Enter a x: x
파이썬 7 에는 11 가지 유형이 있습니다 . 간단한 문장 — 파이썬 3.6.3 문서
복합 문장은 어떻습니까?
In [18]: m = n**2 + 2*n + 1 if n > 0
SyntaxError: invalid syntax
#or
In [19]: m = n**2 + 2*n + 1, if n > 0
SyntaxError: invalid syntax
온다 def
작업을 활성화
In [23]: def m(n):
...: if n > 0:
...: return n**2 + 2*n + 1
...:
In [24]: m(2)
Out[24]: 9
타다, 분석해, 'm'은 이름이고, 'n ** 2 + 2 * n + 1'은 값입니다. :
'='의 변형입니다.
이해를 돕기 위해 모든 것이 과제에서 시작하고 모든 것이 과제 인 경우 찾아보십시오.
이제 lambda
'm'이라는 함수가 있습니다.
시험:
In [28]: m = m(3)
In [29]: m
Out[29]: 16
여기에는 'm'이라는 두 가지 이름이 있으며 함수 m
에는 이미 중복 된 이름이 있습니다.
다음과 같은 형식입니다.
In [27]: m = def m(n):
...: if n > 0:
...: return n**2 + 2*n + 1
SyntaxError: invalid syntax
현명한 전략이 아니므로 오류 보고서
우리는 그중 하나를 삭제하고 이름없이 함수를 설정해야합니다.
m = lambda n:n**2 + 2*n + 1
'익명 기능'이라고합니다
결론적으로,
lambda
수학에서와 같이 하나의 직선으로 함수를 작성할 수있는 인라인 함수lambda
익명이다도움이 되었기를 바랍니다.
자바 스크립트에서, 예를 들어, 함수는 다른 모든 것들과 같은 혼합 된 형태로 취급됩니다 ( int
, string
, float
, bool
). 따라서 즉시 함수를 생성하고 사물에 할당 한 다음 나중에 다시 호출 할 수 있습니다. 유용하지만 과도하게 사용하고 싶지는 않지만 코드를 유지 관리 해야하는 모든 사람들을 혼란스럽게 할 것입니다 ...
이것은이 토끼 구멍이 얼마나 깊은 지 알기 위해 놀고있는 코드입니다.
var x = new Object;
x.thingy = new Array();
x.thingy[0] = function(){ return function(){ return function(){ alert('index 0 pressed'); }; }; }
x.thingy[1] = function(){ return function(){ return function(){ alert('index 1 pressed'); }; }; }
x.thingy[2] = function(){ return function(){ return function(){ alert('index 2 pressed'); }; }; }
for(var i=0 ;i<3; i++)
x.thingy[i]()()();
CS와 관련하여 람다 함수는 수학 표현의 상징적 평가 문제를 다루는 추상 수학 개념입니다. 이러한 맥락에서 람다 함수는 람다 항과 같습니다 .
그러나 프로그래밍 언어에서는 다릅니다. "제자리에"선언되어 있으며 "일류 시민"으로 전달 될 수있는 코드입니다. 이 개념은 거의 모든 대중적인 현대 프로그래밍 언어에 적용되는 데 유용한 것으로 보였습니다 ( 포스트 람다 함수 참조 ).
A는
Lambda Function
, 또는Small Anonymous Function
, 건네 사용자 코드에서 사용할 수있는 기능 자체에 포함 된 블록입니다. - 람다는 다른 프로그래밍 언어에서 다른 이름을 가지고Lambda
있는 파이썬 과 코 틀린 ,Closure
에 스위프트 , 또는Block
에서 C 와 목표 - C를 . 람다의 의미는 이러한 언어와 매우 유사하지만 때로는 약간의 차이가 있습니다.
let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]
func backward(_ n1: String, _ n2: String) -> Bool {
return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)
// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]
reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in
return n1 > n2
})
reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in return n1 > n2 } )
reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )
reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )
reverseOrder = coffee.sorted(by: { $0 > $1 } )
// $0 and $1 are closure’s first and second String arguments.
reverseOrder = coffee.sorted(by: >)
// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]
도움이 되었기를 바랍니다.
나도 알아 나는 이것을 JS로 시도했다.
var addAndMult = function(x) {
return (function(y) {
return (function(z) {
return (x+y)*z;
});
});
};
2 ~ 4를 더한 다음 결과를 6 씩 곱합니다. 그러나 때로는 읽기가 어렵습니다.
또한 흥미로운 forEach 함수를 만들었습니다.
var forEach = function(arr) {
return (function(x) {
for (var i=0; arr[i]; i++) {
x(arr[i]);
}
});
}
forEach ([1,2,3,4,5]) (console.log);
이 방법은 배열을 반복하고 콘솔에 인쇄하는 경우 작업을 수행합니다. 이제 나는 labmdas가 강력한 이유를 얻습니다.
컴퓨터 프로그래밍에서 람다는 외부 소스에서 몇 가지 인수를 취하는 코드 (문장, 표현 또는 그룹)입니다. 항상 익명 함수는 아니어야합니다.이를 구현하는 방법에는 여러 가지가 있습니다.
우리는 수학자들이 가지고 있지 않은 표현, 진술 및 기능을 명확하게 구분합니다.
프로그래밍에서 "함수"라는 단어도 다릅니다. "함수는 수행 할 일련의 단계"(라틴어 "수행"에서)입니다. 수학에서는 변수 간의 상관 관계에 관한 것입니다.
기능적 언어는 가능한 수학 공식과 비슷해 지려고 노력하며 그 단어의 의미는 거의 같습니다. 그러나 다른 프로그래밍 언어에서는 다릅니다.
질문에 완전히 대답했습니다. 자세한 내용을 알고 싶지 않습니다. 녹으로 수치 계산을 쓸 때 사용법을 공유하고 싶습니다.
람다의 예가 있습니다 (익명 함수)
let f = |x: f32| -> f32 { x * x - 2.0 };
let df = |x: f32| -> f32 { 2.0 * x };
Newton-Raphson 방법의 모듈을 작성할 때 1 차 및 2 차 미분으로 사용되었습니다. (Newton–Raphson 방법이 무엇인지 알고 싶다면 " https://en.wikipedia.org/wiki/Newton%27s_method " 를 방문하십시오 .
다음과 같은 출력
println!("f={:.6} df={:.6}", f(10.0), df(10.0))
f=98.000000 df=20.000000
배달 옵션이있는 식당이 있고 30 분 이내에 주문을해야한다고 상상해보십시오. 요점은 고객이 식사를 따뜻하게 묶고 묶는 한 자전거 나 맨발로 자전거로 음식을 보내더라도 걱정하지 않는다는 것입니다. 익명의 정의 된 운송 함수를 사용하여이 관용구를 Javascript로 변환 할 수 있습니다.
아래에서 우리는 일명 전달 방법을 정의했으며 함수에 이름을 정의했습니다.
// ES5
var food = function withBike(kebap, coke) {
return (kebap + coke);
};
화살표 / 람다 함수를 사용하여이 전송을 수행하려면 어떻게해야합니까?
// ES6
const food = (kebap, coke) => { return kebap + coke };
고객에게는 차이가 없으며 음식을 보내는 방법에 대해 생각할 시간이 없습니다. 보내주세요.
Btw, 나는 코크스가있는 kebap을 권장하지 않기 때문에 위 코드가 오류를 유발하는 이유입니다. 즐기세요