Apa perbedaan antara fungsi dan lambda?

54

Saya sedikit bingung tentang 'fungsi' dan 'lambda'. Saya telah melihat beberapa contoh yang menunjukkan bahwa kata kunci skema lambdabekerja sangat mirip dengan kata kunci JavaScript function, tetapi saya benar-benar tidak tahu bagaimana mereka terkait.

Saya diberitahu bahwa 'fungsi' dan 'metode' dapat digunakan secara bergantian ketika berbicara tentang objek di .net. Saya bertanya-tanya apakah 'lambda' dan 'fungsi' memiliki arti yang sama. Saya bertanya-tanya apakah 'lambda' memiliki makna esoteris, melihat bahwa huruf Yunani lambda (λ) muncul di begitu banyak avatar di situs ini. Untuk membuat hal-hal menjadi lebih membingungkan, dalam .net, bagian fungsional dari C # merujuk pada ekspresi fungsi yang dilewatkan ke fungsi lain sebagai 'ekspresi lambda', sehingga kata tersebut sepertinya benar-benar ada di semua tempat.

Saya juga tidak asing dengan istilah 'lambda calculus'.

Apa perbedaan antara fungsi dan lambda?

Cookies Tepung Beras
sumber
3
Nitpick - mereka disebut "ekspresi lambda", bukan "fungsi lambda", setidaknya sejauh dokumentasi C # /. NET berjalan.
Oded
@ TWith2Sugars - Baca pesannya. Jawaban Anda berkualitas rendah karena cukup banyak hanya tautan, jadi dikonversikan ke komentar.
Oded
17
I wonder if 'lambda' has some esoteric meaning, seeing that the Greek letter lambda (λ) appears in so many avatars on this site.Orang akan berharap itu mengacu pada kalkulus lambda, tapi aku punya perasaan aneh Half Life yang harus disalahkan untuk avatar lambda.
yannis
3
Cukup adil, inilah tautan ke jawaban stackoverflow
TWith2Sugars
@ZaphodBeeblebrox: Saya curiga Anda benar tentang pengaruh Half-Life. : /
FrustratedWithFormsDesigner

Jawaban:

44

Kata "lambda" atau "ekspresi lambda" paling sering merujuk pada fungsi anonim. Jadi dalam arti itu lambda adalah semacam fungsi, tetapi tidak setiap fungsi adalah lambda (yaitu fungsi yang disebut biasanya tidak disebut sebagai lambda). Bergantung pada bahasanya, fungsi anonim sering diimplementasikan secara berbeda dari fungsi yang disebutkan (terutama dalam bahasa di mana fungsi anonim ditutup dan fungsi yang disebutkan tidak), jadi merujuk pada mereka dengan istilah yang berbeda dapat masuk akal.

Perbedaan antara kata kunci lambda skema dan kata kunci fungsi Javascript adalah bahwa yang kedua dapat digunakan untuk membuat fungsi anonim dan fungsi yang dinamai sementara yang sebelumnya hanya membuat fungsi anonim (dan Anda akan gunakan defineuntuk membuat fungsi bernama).

Kalkulus lambda adalah bahasa pemrograman minimal / model matematika perhitungan, yang menggunakan fungsi sebagai satu-satunya "struktur data". Dalam kalkulus lamdba, simbol lambda digunakan untuk membuat fungsi (anonim). Di sinilah penggunaan istilah "lambda" dalam bahasa lain berasal.

sepp2k
sumber
1
Itu sangat kasar. Anda menggunakan define(atau letsalah satu kerabatnya, atau internal yang menentukan) untuk membuat nama - itu saja. Tidak ada yang istimewa definesehubungan dengan fungsi.
Eli Barzilay
2
@EliBarzilay Yah, define memang memiliki bentuk khusus untuk mendefinisikan fungsi (yaitu Anda dapat menulis (define (f x) (foo))alih-alih (define f (lambda (x) (foo)))), tetapi poin saya adalah bahwa Anda tidak dapat membuat fungsi bernama menggunakan lambdasendiri, yaitu Anda tidak dapat menulis sesuatu seperti (lambda f (x) (foo))mendefinisikan fungsi bernama fyang membutuhkan satu argumen seperti yang Anda bisa dengan functionkata kunci Javascript .
sepp2k
1
definememiliki itu sebagai gula sintaksis, sehingga tidak sepenting perannya sebagai alat pengikat nama untuk semua nilai. Adapun lambdatidak membuat nama dengan sendirinya: itu fitur penting, karena memisahkan pemberian nama dari bentuk fungsi ... IMO JS melakukan hal yang benar dalam memungkinkan pemisahan sementara juga menerima nama opsional untuk massa yang akan merasa ngeri pada gagasan fungsi tanpa nama. (Dan untungnya ukuran massa tersebut menurun secara umum ...)
Eli Barzilay
18

Lambda hanyalah fungsi anonim - fungsi tanpa nama.

Oded
sumber
4
Catatan Cukup: lambda dapat berisi negara (seperti dalam penutupan tidak) bahwa mereka mengambil dari konteks di mana mereka dinyatakan.
Martin York
7
Begitu juga dengan fungsi bernama, jika bahasa memungkinkan Anda mendeklarasikan fungsi bersarang.
cao
4
Kudos telah membuatnya menjadi tab review "posting berkualitas rendah" dengan jawaban yang tervvotifikasi.
yannis
@ZaphodBeeblebrox - Tidak sengaja, saya dapat meyakinkan Anda.
Oded
Tidak juga, lambdaekspresi dalam Skema seperti functionekspresi tanpa nama - tetapi tidak ada yang menghentikan Anda dari memberi nama pada mereka. Sebagai contoh var f = [function(x){return x;}][0]. Anda bisa berpendapat bahwa nilai fungsi itu sendiri tidak memiliki nama, tetapi itu akan berlaku untuk semua fungsi ...
Eli Barzilay
8

Dalam C # fungsi anonim adalah istilah umum yang mencakup ekspresi lambda dan metode anonim (metode anonim adalah contoh delegasi tanpa deklarasi metode aktual).

Ekspresi Lambda dapat dipecah menjadi ekspresi lambda dan pernyataan lambda

Ekspresi lambda:

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

Pernyataan lambda mirip dengan ekspresi lambda kecuali pernyataan terlampir dalam kurung:

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

Ketika kita berbicara tentang ekspresi lambda dalam JavaScript yang pada dasarnya berarti menggunakan fungsi sebagai argumen dalam panggilan ke fungsi lain.

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
Christian P
sumber
+1 Banyak orang telah menyebutkan bahwa lambda adalah fungsi anonim, tetapi ada lebih dari itu. Tubuh (sisi kanan) lambda sering merupakan ekspresi daripada blok pernyataan. Badan fungsi yang disebut ekspresi biasanya diizinkan (atau diperlukan) dalam bahasa fungsional, tetapi bukan bahasa yang sangat penting.
Zantier
4

TL; DR Seperti yang ditunjukkan orang lain: notasi lambda hanyalah cara untuk mendefinisikan fungsi tanpa dipaksa untuk memberi mereka nama.

Versi panjang

Saya ingin menguraikan sedikit tentang topik ini karena saya merasa sangat menarik. Penafian: Saya sudah lama mengikuti kalkulus lambda. Jika seseorang dengan pengetahuan yang lebih baik menemukan kesalahan dalam jawaban saya, jangan ragu untuk membantu saya meningkatkannya.

Mari kita mulai dengan ekspresi, misalnya 1 + 2dan x + 2. Literal seperti 1dan 2disebut konstanta karena terikat dengan nilai tetap tertentu.

Identifier seperti xdisebut variabel dan untuk mengevaluasinya Anda harus mengikatnya ke beberapa nilai terlebih dahulu. Jadi, pada dasarnya Anda tidak dapat mengevaluasi x + 1selama Anda tidak tahu apa xitu.

Notasi lambda menyediakan skema untuk mengikat nilai input spesifik ke variabel. Sebuah ekspresi lambda dapat dibentuk dengan menambahkan λx .di depan sebuah ekspresi yang ada, misalnya λx . x + 1. Variabel xdikatakan bebas di x + 1dan terikat diλx . x + 1

Bagaimana ini membantu dalam mengevaluasi ekspresi? Jika Anda memberi nilai pada ekspresi lambda, seperti itu

(λx . x + 1) 2

maka Anda dapat mengevaluasi seluruh ekspresi dengan mengganti (mengikat) semua kemunculan variabel xdengan nilai 2:

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

Jadi, notasi lambda menyediakan mekanisme umum untuk mengikat hal-hal ke variabel yang muncul dalam blok ekspresi / program. Bergantung pada konteksnya, ini menciptakan konsep yang sangat berbeda dalam bahasa pemrograman:

  • Dalam bahasa murni fungsional seperti Haskell, ekspresi lambda mewakili fungsi dalam arti matematika: nilai input disuntikkan ke dalam tubuh lambda dan nilai output dihasilkan.
  • Dalam banyak bahasa (misalnya JavaScript, Python, Skema) mengevaluasi tubuh ekspresi lambda dapat memiliki efek samping. Dalam hal ini orang dapat menggunakan istilah prosedur untuk menandai perbedaan fungsi murni.

Terlepas dari perbedaan, notasi lambda adalah tentang mendefinisikan parameter formal dan mengikatnya ke parameter aktual.

Langkah selanjutnya, adalah memberi fungsi / prosedur nama. Dalam beberapa bahasa, fungsi adalah nilai seperti yang lain, sehingga Anda dapat memberi nama fungsi sebagai berikut:

(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

Seperti yang ditunjukkan Eli Barzilay, definisi ini hanya mengikat nama fpada suatu nilai, yang kebetulan merupakan suatu fungsi. Jadi dalam hal ini, fungsi, angka, string, karakter adalah semua nilai yang dapat diikat ke nama dengan cara yang sama:

(define n 42)   ;; Scheme

n = 42          -- Haskell

val n: Int = 42 // Scala

var n = 42      // JavaScript

n = 42          # Python

Dalam bahasa ini Anda juga dapat mengikat fungsi ke nama menggunakan notasi yang lebih akrab (tapi setara):

(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

Beberapa bahasa, misalnya C, hanya mendukung notasi terakhir untuk mendefinisikan (bernama) fungsi.

Penutupan

Beberapa pengamatan terakhir tentang penutupan . Pertimbangkan ungkapannya x + y. Ini mengandung dua variabel gratis. Jika Anda mengikat xmenggunakan notasi lambda Anda mendapatkan:

\x -> x + y

Ini bukan (belum) fungsi karena masih berisi variabel gratis y. Anda bisa membuat fungsi dengan mengikat yjuga:

\x -> \y -> x + y

atau

\x y -> x + y

yang sama dengan +fungsinya.

Tetapi Anda dapat mengikat, katakanlah, ydengan cara lain (*):

incrementBy y = \x -> x + y

Hasil penerapan kenaikan fungsi Dengan angka adalah penutupan, yaitu fungsi / prosedur yang badannya berisi variabel bebas (misalnya y) yang telah terikat pada nilai dari lingkungan di mana penutupan didefinisikan.

Begitu incrementBy 5juga fungsi (penutupan) yang menambah angka dengan 5.

CATATAN (*)

Saya sedikit curang di sini:

incrementBy y = \x -> x + y

setara dengan

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

jadi mekanisme pengikatannya sama. Secara intuitif, saya berpikir tentang penutupan sebagai mewakili sebagian dari ekspresi lambda yang lebih kompleks. Ketika representasi ini dibuat, beberapa binding dari ekspresi ibu telah ditetapkan dan penutupan menggunakannya nanti ketika akan dievaluasi / dipanggil.

Giorgio
sumber
Saya hanya pemula, tetapi saya pikir ini bisa sedikit membingungkan jika Anda mencoba memahami kalkulus dalam arti matematika, karena apa yang Anda sebut konstanta disebut variabel dan dilambangkan dengan simbol a, b, c ... Apa yang Anda variabel panggilan akan menjadi variabel yang tidak ditentukan x . Di sisi lain 1 adalah λ f x . f x , 2 adalah λ f x . f ( f x ) dan seterusnya.
jinawee
@jinawee: Saya akui saya tidak mencari definisi yang tepat. Saya ingat menggunakan variabel istilah dan konstanta dalam logika. Di sana, konstanta adalah simbol yang dipetakan ke domain, sedangkan variabel adalah simbol yang dapat Anda kuantifikasi. Tapi, sekali lagi, (1) itu sudah lama sekali sejak saya mengambil kursus tentang logika, dan (2) lambda-calculus tidak perlu mengikuti 1-1 konsep logika matematika. Jika Anda mengarahkan saya ke referensi, saya dapat mencoba dan memperbaiki terminologi saya.
Giorgio
0

"Lambda" dalam pemrograman biasanya berarti "fungsi lambda" (atau juga "ekspresi lambda", "istilah lambda"). Ketika fungsi adalah blok kode bernama yang ditentukan sebelum penggunaannya, "fungsi lambda" adalah blok kode (atau ekspresi) yang didefinisikan sebagai pengganti penggunaan yang dapat digunakan sebagai warga negara kelas satu dalam bahasa pemrograman.

Dalam JavaScript ES6 (2015) ada sintaks pendek untuk mendefinisikan lambdas yang disebut "Fungsi Panah" . Dalam C # sintaks tersebut diperkenalkan di .NET 3.0 (sekitar 2006) .

Dalam matematika gagasan "fungsi" memiliki beberapa makna di mana salah satu artinya adalah tentang notasi fungsi (yaitu cara menuliskannya), kemudian "fungsi lambda" (dalam kalkulus) adalah jenis khusus notasi fungsi. Untuk diskusi lebih lanjut, periksa fungsi lambda dalam bahasa pemrograman .

battlmonstr
sumber