it-swarm-id.com

Apa itu lambda, dan mengapa itu berguna?

Sejauh ini saya mendengar tentang:

  • Kalkulus Lambda
  • Pemrograman Lambda
  • Ekspresi Lambda
  • Fungsi Lambda

Yang semuanya tampaknya terkait dengan pemrograman fungsional ...

Tampaknya itu akan diintegrasikan ke dalam C++ 1x, jadi saya mungkin lebih mengerti sekarang:

http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions

Dapatkah seseorang mendefinisikan secara singkat apa saja hal-hal lambdas dan memberikan di mana itu dapat bermanfaat?

55
jokoon
  • Kalkulus Lambda

Kalkulus lambda adalah model perhitungan yang ditemukan oleh Gereja Alonzo pada usia 30-an. Sintaks dan semantik dari kebanyakan 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 digunakan untuk buat fungsi anonim dalam banyak bahasa berbasis LISP untuk alasan yang sama).

  • Pemrograman Lambda

Ini bukan istilah yang umum digunakan, tapi saya berasumsi itu berarti pemrograman menggunakan fungsi anonim atau pemrograman menggunakan fungsi tingkat tinggi.


Sedikit informasi lebih lanjut 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 mis. meneruskan fungsi perbandingan ke fungsi penyortiran. Namun ada batas kegunaannya:

Sebagai contoh jika Anda ingin mengurutkan vektor vektor dengan elemen ith dari masing-masing vektor (di mana i adalah parameter run-time), Anda tidak dapat menyelesaikan ini dengan pointer fungsi. Fungsi yang membandingkan dua vektor dengan elemen ith 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 metode operator(). Sekarang kita dapat mendefinisikan kelas CompareByIthElement, yang menggunakan argumen i sebagai argumen konstruktor dan kemudian mengambil dua vektor untuk dibandingkan sebagai argumen ke metode operator(). Untuk mengurutkan vektor vektor dengan elemen ith kita sekarang dapat membuat objek CompareByIthElement dengan i sebagai argumen dan kemudian meneruskan objek itu ke fungsi sortir.

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 seperti CompareByIthElement* dan dengan demikian 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 elemen ith sedikit verbose jika Anda hanya akan menggunakannya sekali untuk mengurutkan vektor. Bahkan dalam kasus di mana Anda hanya perlu pointer fungsi, mendefinisikan fungsi bernama adalah sub-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 lambda literal seperti [x1, x2](y1,y2){bla} kode yang dihasilkan yang pada dasarnya melakukan hal berikut:

  1. Tentukan kelas yang memiliki dua variabel anggota (x1 Dan x2) Dan operator() dengan argumen (y1 Dan y2) dan tubuh bla.
  2. Buat turunan dari kelas, atur variabel anggota x1 Dan x2 Ke 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 perpustakaan standar), akan menerima lambdas, tetapi fungsi apa pun yang hanya menerima pointer fungsi tidak akan.

43
sepp2k

Pada dasarnya, fungsi lambda adalah fungsi yang Anda buat "on the fly". Dalam C++ 1x mereka dapat digunakan untuk meningkatkan dukungannya untuk pemrograman fungsional:

std::for_each( begin, end, [](int i){std::cout << i << '\n';} );

Ini kira-kira akan menghasilkan kode yang mirip dengan yang ini:

struct some_functor {
  void operator()(int i) {std::cout << i << '\n';}
};

std::for_each( begin, end, some_functor() );

Jika Anda membutuhkan some_functor Hanya untuk satu panggilan ke std::for_each(), maka fungsi lambda memiliki beberapa keunggulan di atasnya:

  • apa yang dilakukan dalam loop ditentukan tepat di mana fungsi looping dipanggil
  • itu membebaskan Anda dari menulis beberapa kode boiler-plate
  • tidak ada functor tergeletak di beberapa lingkup namespace yang membuat semua orang melihat kode bertanya-tanya apa yang dibutuhkan untuk itu
18
sbi

Fungsi lambda adalah nama lain untuk fungsi anonim - pada dasarnya fungsi tanpa nama.

Biasanya Anda menggunakan ini dalam bahasa di mana Anda hanya perlu menggunakan fungsi satu kali. Misalnya bukannya

def add(a, b)
  return a+b

dan kemudian meneruskan fungsi itu ke fungsi lain seperti itu

reduce(add, [5,3,2])

Dengan lambda, Anda cukup melakukannya

reduce(lambda x, y: a+b, [5,3,2])
7
Martin Konecny