Bir işlev ile bir lambda arasındaki fark nedir?


54

'Fonksiyon' ve 'lambda' hakkında biraz kafam karıştı. Scheme anahtar sözcüğünün lambdaJavaScript anahtar kelimesine çok benzer şekilde çalıştığını gösteren bazı örnekler gördüm function, ancak bunların nasıl bir ilişki olduğunu gerçekten bilmiyorum.

Bana 'işlev' ve 'yöntem' in .net'teki nesnelerden bahsederken birbirlerinin yerine kullanılabileceği söylenir. Acaba 'lambda' ve 'fonksiyon' da aynı şeyi ifade ediyor mu? 'Lambda'nın ezoterik bir anlamı olup olmadığını merak ediyorum, Yunanca lambda (λ) harfinin bu sitede pek çok avatarda göründüğünü görünce. Net olmayan şeyleri daha da karışık hale getirmek için, C # 'nin işlevsel kısımları başka bir işleve geçirilen işlev ifadelerini' lambda ifadeleri 'olarak adlandırır, bu nedenle kelime gerçekten her yerde görünüyor.

Ayrıca 'lambda calculus' terimine de tanıdık geliyorum.

Bir işlev ile bir lambda arasındaki fark nedir?


3
Nitpick - En azından C # /. NET belgelerine kadar "lambda fonksiyonları" değil, "lambda ifadeleri" olarak adlandırılırlar.
Oded

@ TWith2Sugars - Mesajı oku. Cevabınız düşük kaliteli çünkü hemen hemen bir bağlantı, bu yüzden bir yoruma dönüştürüldü.
Oded

17
I wonder if 'lambda' has some esoteric meaning, seeing that the Greek letter lambda (λ) appears in so many avatars on this site.Birisi lambda matematiğine atıfta bulunacağını ümit ederdim, ama tuhaf bir hisim var Half Life lambda avatarlarını suçluyor.
Yannis

3
Yeterince adil, burada stackoverflow cevabının bağlantısı: stackoverflow.com/questions/16501/what-is-a-lambda-function
TWith2Sugars

@ ZahodBeeblebrox: Half-Life etkisi konusunda haklı olduğunuzdan şüpheleniyorum. : /
SinirliFormsDesigner'da

Yanıtlar:


44

"Lambda" veya "lambda ifadeleri" kelimesi çoğunlukla isimsiz fonksiyonları ifade eder. Dolayısıyla bu anlamda bir lambda bir tür işlevdir, ancak her işlev bir lambda değildir (yani adlandırılmış işlevler genellikle lambdalar olarak adlandırılmaz). Dile bağlı olarak, anonim işlevler genellikle adlandırılmış işlevlerden farklı olarak uygulanır (özellikle adsız işlevlerin kapandığı ve adlandırılmış işlevlerin bulunmadığı dillerde), bu nedenle bunlara farklı terimlerle atıfta bulunmak anlamlı olabilir.

Şema'nın lambda anahtar sözcüğü ve Javascript'in fonksiyon anahtar sözcüğü arasındaki fark, ikincisinin hem adsız işlevler hem de adlandırılmış işlevler oluşturmak için kullanılabileceği ve eski isim yalnızca işlevsiz işlevler oluştururken (ve defineadlandırılmış işlevler oluşturmak için kullanacağınız ).

Lambda matematiği, sadece "veri yapısı" olarak kullanılan fonksiyonları kullanan minimal bir programlama dili / matematiksel hesaplama modelidir. Lamdba hesaplarında lambda sembolü (anonim) işlevler oluşturmak için kullanılır. Bu, "lambda" teriminin diğer dillerde kullanımından kaynaklanmaktadır.


1
Bu çok zor. İsimler oluşturmak için define(veya letveya yakınlarından birini veya dahili bir tanımını) kullanırsınız - hepsi bu. defineİşlevlerle ilgili özel bir şey yok .
Eli Barzilay

2
@EliBarzilay Eh, define yapar (siz yazabilirsiniz yani işlevleri tanımlamak için özel bir form var (define (f x) (foo))yerine (define f (lambda (x) (foo)))), ama benim açımdan kullandığınız adlandırılmış işlevi oluşturamaz olmasıydı lambdagibi, tek başına bir şey yazamaz yani (lambda f (x) (foo))adında bir işlevi tanımlamak için fJavascript'in functionanahtar kelimesiyle sizin gibi bir argüman alır .
sepp2k

1
defineBunu sözdizimsel bir şeker kadar vardır, bu yüzden tüm değerler için isim bağlama aracı rolü kadar önemli değildir. Kendi lambdabaşına bir isim oluşturmadığı için: bu önemli bir özelliktir, çünkü isimleri fonksiyon biçimlerinden vermekten ayırır ... IMO JS, dehşete kapılacak kitleler için isteğe bağlı bir isim kabul ederken, ayrılmaya izin vermede doğru olanı yapmaktadır. isimsiz bir fonksiyon fikri. (Ve neyse ki, bu kitlelerin büyüklüğü genel bir düşüş içerisinde ...)
Eli Barzilay

18

Bir lambda sadece isimsiz bir fonksiyondur - isimsiz bir fonksiyon.


4
Not Oldukça: lambda, bildirildiği bağlamdan koptukları (kapandığı gibi) durumlarını içerebilir.
Martin York

7
Dil, iç içe geçmiş işlevleri bildirmenize izin veriyorsa, adlandırılmış bir işlev olabilir.
cHao

4
Olumlu bir cevap ile "düşük kaliteli mesajlar" inceleme sekmesine yapmak için Kudos.
yannis

@ZaphodBeeblebrox - Bilerek değil, sizi temin ederim.
Oded

Gerçekten de, lambdaScheme'deki bir ifade tıpkı isimsiz bir functionifade gibi - ama daha sonra onlara bir isim vermekten alıkoyacak hiçbir şey yok. Örneğin var f = [function(x){return x;}][0]. İşlev değerinin adının olmadığını, ancak tüm işlevler için geçerli olacağını iddia edebilirsiniz ...
Eli Barzilay


8

C # Anonim işlevi , hem lambda ifadelerini hem de anonim yöntemleri içeren genel bir terimdir (anonim yöntemler, gerçek yöntem bildirimi olmadan temsilci örneklerdir).

Lambda ifadeleri için bölünebilir ifade lambda ve deyim lambda

İfade lambdası:

(int x, string y) => x == y.Length 

İfade lambda ifadesi (ler) parantez içine alınmış dışında ifade lambda'ya benzer:

(int x, string y) => {
         if (x == y.Length) {
             Console.WriteLine(y);
         }
}

JavaScript'teki lambda ifadeleri hakkında konuştuğumuzda, bu temelde sadece bir işlevi başka bir işlev çağrısında argüman olarak kullanmak anlamına gelir.

var calculate = function(x, y, operation){
    return operation(x, y);
}

// we're passing anonymous function as a third argument
calculate(10, 15, function(x, y) {
    return x + y;
}); // 25

+1 Birçok kişi lambdaların anonim işlevler olduğunu belirtti, fakat bundan daha fazlası var. Bir lambdanın gövdesi (sağ taraf) genellikle bir ifade bloğu yerine bir ifadedir . Bir adlandırılmış işlevin bir ifadesi olması, işlevsel dillerde genellikle zorunlu dillerde izin verilir (veya zorunludur).
Zantier

4

TL; DR Diğerlerinin de belirttiği gibi: lambda notasyonu sadece bir isim vermek zorunda kalmadan fonksiyonları tanımlamanın bir yoludur.

Uzun versiyon

Bu konuyu biraz ele almak istiyorum, çünkü çok ilginç buluyorum. Feragatname: Lamda calculus kursumu uzun zaman önce aldım. Daha iyi bilgiye sahip biri cevabımda herhangi bir yanlışlık bulursa, geliştirmeme yardımcı olmaktan çekinmeyin.

İfadelerle başlayalım, örneğin 1 + 2ve x + 2. Gibi Değişmez 1ve 2denir sabitleri bunlar belirli sabit değerlere bağlıdırlar çünkü.

Gibi bir tanımlayıcı değişken olarak xadlandırılır ve değerlendirmek için önce onu bir değere bağlamanız gerekir. Yani, temelde ne olduğunu bilmediğiniz sürece değerlendiremezsiniz .x + 1x

Lambda notasyonu, belirli girdi değerlerini değişkenlere bağlamak için bir şema sağlar. Bir lambda ifadesi , λx .mevcut bir ifadenin önüne, örneğin λx . x + 1; Değişken xolduğu söylenir serbest olarak x + 1ve bağlı olarakλx . x + 1

Bu ifadelerin değerlendirilmesinde nasıl yardımcı olur? Lambda ifadesine bir değer beslerseniz, bunun gibi

(λx . x + 1) 2

o zaman tüm ifadeyi değişkenin tüm oluşumlarını x2 değeri ile değiştirerek (bağlayarak) değerlendirebilirsiniz :

(λx . x + 1) 2
      2 + 1
      3

Bu nedenle, lambda gösterimi, bir ifade / program bloğunda görünen değişkenlere şeyleri bağlamak için genel bir mekanizma sağlar. Bağlama bağlı olarak, bu programlama dillerinde çok farklı farklı kavramlar yaratır:

  • Haskell gibi tamamen işlevsel bir dilde, lambda ifadeleri matematiksel anlamda işlevleri temsil eder : lambda gövdesine bir girdi değeri enjekte edilir ve bir çıktı değeri üretilir.
  • Bir lambda ifadesinin gövdesini değerlendiren birçok dilde (örneğin, JavaScript, Python, Şema) yan etkileri olabilir. Bu durumda kişi, saf işlevler arasındaki farkı işaretlemek için yordam terimini kullanabilir .

Farklılıkların yanı sıra, lambda gösterimi resmi parametreleri tanımlamak ve bunları gerçek parametrelere bağlamakla ilgilidir.

Bir sonraki adım, bir fonksiyon / prosedüre bir isim vermektir. Çeşitli dillerde, fonksiyonlar diğerleri gibi değerlerdir, bu nedenle bir fonksiyona aşağıdaki gibi bir ad verebilirsiniz:

(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'ın işaret ettiği gibi, bu tanım sadece ismi fbir işlev olan bir değere bağlar . Dolayısıyla bu açıdan fonksiyonlar, sayılar, dizeler, karakterler aynı şekilde isimlere bağlanabilecek değerlerdir:

(define n 42)   ;; Scheme

n = 42          -- Haskell

val n: Int = 42 // Scala

var n = 42      // JavaScript

n = 42          # Python

Bu dillerde, daha bilinen (ancak eşdeğer) gösterimini kullanarak bir isme bir işlev de bağlayabilirsiniz:

(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

Bazı diller, örneğin C, yalnızca belirtilen (adlandırılmış) fonksiyonları tanımlamak için kullanılan notasyonu destekler.

Kapaklar

Kapanışlarla ilgili bazı son gözlemler . İfadeyi düşünün x + y. Bu iki serbest değişken içerir. xLamda notasyonu kullanarak bağlanırsanız , şunları elde edersiniz:

\x -> x + y

Bu (henüz) bir fonksiyon değildir çünkü hala bir serbest değişken içermektedir y. Bunun dışında bir işlev yde bağlayarak yapabilirsiniz :

\x -> \y -> x + y

veya

\x y -> x + y

bu sadece +fonksiyonla aynıdır .

Ama ybaşka bir şekilde (*):

incrementBy y = \x -> x + y

Bir sayıya fonksiyon artışı uygulamanın sonucu bir kapaktır, yani gövdesi y, kapağın tanımlandığı ortamdan bir değere bağlı serbest bir değişken (örneğin ) içeren bir fonksiyon / prosedürdür .

Öyleyse incrementBy 5, sayıları 5 oranında artıran işlev (kapatma).

NOT (*)

Burada biraz hile yapıyorum:

incrementBy y = \x -> x + y

eşittir

incrementBy = \y -> \x -> x + y

bu yüzden bağlama mekanizması aynıdır. Sezgisel olarak, daha karmaşık bir lambda ifadesinin bir yığınını temsil eden bir kapanma olduğunu düşünüyorum. Bu temsil oluşturulduğunda, ana ifadenin bazı bağları çoktan ayarlanmıştır ve kapatma, değerlendirildiği / çağrıldığı zaman bunları daha sonra kullanır.


Ben sadece bir yalvarıyorum, ama matematiksel anlamda λ matematiği anlamaya çalışıyorsanız, bunun biraz kafa karıştırıcı olabileceğini düşünüyorum, çünkü sabit olarak adlandırdığınız şeye değişkenler denir ve a, b, c ... çağrı değişkenleri, belirlenmemiş bir x değişkeni olacaktır . Öte yandan 1 Açık λ olan f x . f x , 2 λ f x'dir . f ( f x ) vb.
jinawee

@jinawee: Kesin tanımı anlamadım. Değişkenler ve sabit terimlerini mantıkta kullanmayı hatırlıyorum Burada bir sabit, bir etki alanı ile eşlenen bir semboldür, değişken ise ölçebileceğiniz bir semboldür. Fakat yine de, (1) mantık üzerine bir kurs aldığımdan bu yana çok zaman geçti ve (2) lambda-matematiğinin matematiksel mantık kavramlarını 1-1 izlemesi gerekmiyor. Beni bir referansa yönlendirirseniz terminolojimi düzeltmeyi deneyebilirim.
Giorgio

0

Programlamada "Lambda" genellikle "lambda işlevi" (veya ayrıca "lambda ifadesi", "lambda terimi") anlamına gelir. İşlev, kullanımından önce tanımlanmış bir kod bloğu olduğunda, "lambda işlevi", bir programlama dilinde birinci sınıf vatandaş olarak kullanılabilecek kullanım yerine tanımlanan bir kod bloğu (veya ifade) şeklindedir.

JavaScript ES6'da (2015) "Ok İşlevleri" adlı lambdaları tanımlamak için kısa bir sözdizimi vardır . C # 'da bu sözdizimi .NET 3.0'da (yaklaşık 2006) tanıtıldı .

Matematikte bir "fonksiyon" kavramı, anlamlardan birinin bir fonksiyonun gösterimi ile ilgili olduğu (yani nasıl yazılacağı), daha sonra "lambda fonksiyonu" (hesaplamalı) özel bir fonksiyon gösterimi olduğu çeşitli anlamlara sahiptir. Daha fazla tartışma için programlama dillerinde lambda fonksiyonlarını kontrol edin .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.