Kalkulus lambda adalah model perhitungan yang ditemukan oleh Gereja Alonzo pada usia 30-an. Sintaks dan semantik dari sebagian besar bahasa pemrograman fungsional secara langsung atau tidak langsung terinspirasi oleh kalkulus lambda.
Kalkulus lambda dalam bentuk paling dasar memiliki dua operasi: Abstraksi (membuat fungsi (anonim)) dan aplikasi (menerapkan fungsi). Abstraksi dilakukan menggunakan operator λ, memberi nama lambda kalkulus.
- Ekspresi Lambda
- Fungsi Lambda
Fungsi anonim sering disebut "lambdas", "fungsi lambda" atau "ekspresi lambda" karena, seperti yang saya katakan di atas, λ adalah simbol untuk membuat fungsi anonim dalam kalkulus lambda (dan kata lambda
itu digunakan untuk membuat fungsi anonim di banyak bahasa) bahasa berbasis untuk alasan yang sama).
Ini bukan istilah yang umum digunakan, tapi saya berasumsi itu berarti pemrograman menggunakan fungsi anonim atau pemrograman menggunakan fungsi tingkat tinggi.
Sedikit lebih banyak informasi tentang lambdas di C ++ 0x, motivasi mereka dan bagaimana mereka berhubungan dengan fungsi pointer (banyak dari ini mungkin merupakan pengulangan dari apa yang sudah Anda ketahui, tapi saya harap ini membantu menjelaskan motivasi lambdas dan bagaimana perbedaannya. dari pointer fungsi):
Pointer fungsi, yang sudah ada di C, cukup berguna untuk misal meneruskan fungsi perbandingan ke fungsi sortir. Namun ada batas kegunaannya:
Misalnya jika Anda ingin mengurutkan vektor vektor dengan i
elemen th dari masing-masing vektor (di mana i
parameter run-time), Anda tidak bisa menyelesaikan ini dengan pointer fungsi. Sebuah fungsi yang membandingkan dua vektor dengan i
elemen th mereka , perlu mengambil tiga argumen ( i
dan dua vektor), tetapi fungsi pengurutan akan membutuhkan fungsi yang mengambil dua argumen. Apa yang kita perlukan adalah cara untuk menyediakan argumen i
ke fungsi sebelum meneruskannya ke fungsi sortir, tetapi kita tidak bisa melakukan ini dengan fungsi C biasa.
Untuk mengatasi ini, C ++ memperkenalkan konsep "objek fungsi" atau "functors". Functor pada dasarnya adalah objek yang memiliki operator()
metode. Sekarang kita dapat mendefinisikan kelas CompareByIthElement
, yang mengambil argumen i
sebagai argumen konstruktor dan kemudian mengambil dua vektor untuk dibandingkan sebagai argumen untuk operator()
metode ini. Untuk mengurutkan vektor vektor dengan i
elemen th kita sekarang dapat membuat CompareByIthElement
objek dengan i
sebagai argumen dan kemudian meneruskan objek itu ke fungsi pengurutan.
Karena objek fungsi hanya objek dan bukan fungsi teknis (meskipun mereka dimaksudkan untuk berperilaku seperti mereka), Anda tidak dapat membuat pointer fungsi menunjuk ke objek fungsi (Anda tentu saja dapat memiliki pointer ke objek fungsi, tetapi akan memiliki tipe like CompareByIthElement*
dan karenanya tidak menjadi pointer fungsi).
Sebagian besar fungsi di pustaka standar C ++ yang mengambil fungsi sebagai argumen didefinisikan menggunakan templat sehingga berfungsi dengan pointer fungsi serta objek fungsi.
Sekarang untuk lambdas:
Mendefinisikan seluruh kelas untuk dibandingkan dengan i
elemen th adalah sedikit bertele-tele jika Anda hanya akan menggunakannya sekali untuk mengurutkan vektor. Bahkan dalam kasus di mana Anda hanya memerlukan pointer fungsi, mendefinisikan fungsi bernama tidak optimal jika hanya digunakan sekali karena a) itu mencemari namespace dan b) fungsi biasanya akan sangat kecil dan tidak ada yang benar-benar alasan yang bagus untuk abstrak logika ke dalam fungsinya sendiri (selain itu Anda tidak dapat memiliki pointer fungsi tanpa mendefinisikan suatu fungsi).
Jadi untuk memperbaiki lambda ini diperkenalkan. Lambdas adalah objek fungsi, bukan pointer fungsi. Jika Anda menggunakan [x1, x2](y1,y2){bla}
kode seperti lambda literal dihasilkan yang pada dasarnya melakukan hal berikut:
- Tentukan kelas yang memiliki dua variabel anggota (
x1
dan x2
) dan operator()
dengan argumen ( y1
dan y2
) dan tubuh bla
.
- Buat turunan dari kelas, pengaturan variabel anggota
x1
dan x2
nilai-nilai variabel x1
dan x2
saat ini dalam ruang lingkup.
Jadi lambda berperilaku seperti objek fungsi, kecuali bahwa Anda tidak dapat mengakses kelas yang dihasilkan untuk mengimplementasikan lambda dengan cara apa pun selain menggunakan lambda. Akibatnya setiap fungsi yang menerima functors sebagai argumen (pada dasarnya berarti fungsi non-C di pustaka standar), akan menerima lambdas, tetapi fungsi apa pun yang hanya menerima pointer fungsi tidak akan.