it-swarm.dev

Lambda nedir ve neden yararlı olur?

Şimdiye kadar duydum:

  • Lambda hesabı
  • Lambda programlama
  • Lambda ifadeleri
  • Lambda fonksiyonları

Bunların hepsi fonksiyonel programlama ile ilgili gibi görünüyor ...

Görünüşe göre C++ 1x'e entegre edilecek, bu yüzden şimdi daha iyi anlayabilirim:

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

Birisi lambdas şeylerinin ne olduğunu kısaca tanımlayabilir ve faydalı olabileceği bir yeri verebilir mi?

55
jokoon
  • Lambda hesabı

Lambda hesabı, 30'larda Alonzo Kilisesi tarafından icat edilen bir hesaplama modelidir. Çoğu işlevsel programlama dilinin sözdizimi ve anlambilimi, lambda hesabı tarafından doğrudan veya dolaylı olarak esinlenmiştir.

En temel biçimindeki lambda hesabı iki işleme sahiptir: Soyutlama (anonim) bir işlev oluşturma) ve uygulama (bir işlev uygulama). Soyutlama, lambda hesabının adını veren λ operatörü kullanılarak gerçekleştirilir.

  • Lambda ifadeleri
  • Lambda fonksiyonları

Anonim işlevlere genellikle "lambdas", "lambda işlevleri" veya "lambda ifadeleri" denir, çünkü yukarıda söylediğim gibi, λ lambda hesabında anonim işlevler oluşturmanın sembolüdür (ve lambda kelimesi aynı nedenden dolayı birçok LISP tabanlı dilde anonim işlevler oluşturun).

  • Lambda programlama

Bu yaygın olarak kullanılan bir terim değildir, ancak anonim işlevler kullanarak programlama veya daha üst düzey işlevler kullanarak programlama anlamına gelir.


C++ 0x'deki lambdalar, motivasyonları ve işlev işaretçileriyle nasıl ilişkili oldukları hakkında biraz daha fazla bilgi (bunun çoğu muhtemelen zaten bildiğinizin bir tekrarıdır, ancak umarım lambdaların motivasyonunu ve nasıl farklı olduklarını açıklamaya yardımcı olur. işlev işaretçilerinden):

C'de zaten mevcut olan işlev işaretçileri, ör. bir karşılaştırma işlevini bir sıralama işlevine geçirir. Bununla birlikte, yararlılıklarının sınırları vardır:

Örneğin, bir vektör vektörünü her vektörün i. Elementine göre sıralamak istiyorsanız (burada i bir çalışma zamanı parametresidir), bunu bir işlev işaretçisi ile çözemezsiniz. . İki vektörü i. Elementiyle karşılaştıran bir fonksiyonun üç argüman alması gerekir (i ve iki vektör), fakat sıralama fonksiyonu iki argüman alan bir fonksiyona ihtiyaç duyacaktır. İhtiyacımız olan şey, bir şekilde i argümanını sıralama işlevine geçirmeden önce işleve sağlamanın bir yoludur, ancak bunu düz C işlevleriyle yapamayız.

Bunu çözmek için, C++ "fonksiyon nesneleri" veya "functors" kavramını tanıttı. Bir işlev temelde operator() yöntemine sahip bir nesnedir. Şimdi bir yapıcı argümanı olarak CompareByIthElement argümanını alan ve daha sonra operator() yöntemiyle argüman olarak karşılaştırılacak iki vektörü alan bir i sınıfı tanımlayabiliriz. Vektörlerin bir vektörünü i. Elemente göre sıralamak için, artık CompareByIthElement nesnesini bağımsız değişken olarak i nesnesi oluşturabilir ve ardından bu nesneyi sıralama işlevine aktarabiliriz.

İşlev nesneleri yalnızca nesneler olduğu ve teknik olarak işlevler olmadığı için (onlar gibi davranmaları istenmesine rağmen), bir işlev nesnesine bir işlev işaretçisi noktası oluşturamazsınız (elbette bir işlev nesnesine bir işaretçi olabilir, ancak CompareByIthElement* gibi bir türe sahip olur ve bu nedenle bir işlev işaretçisi olmaz).

C++ standart kitaplığında işlevleri bağımsız değişken olarak alan işlevlerin çoğu, işlev işaretçileriyle ve işlev nesneleriyle çalışacak şekilde şablonlar kullanılarak tanımlanır.

Şimdi lambdas'a:

i. Öğeyle karşılaştırmak için bir sınıfın tamamını tanımlamak, bir vektörü sıralamak için yalnızca bir kez kullanacaksanız biraz ayrıntılıdır. Yalnızca bir işlev işaretçisine ihtiyaç duyduğunuz durumda bile, adlandırılmış bir işlevi tanımlamak yalnızca bir kez kullanılırsa en uygunudur çünkü a) ad alanını kirletir ve b) işlev genellikle çok küçük olur ve gerçekten yoktur mantığı kendi işlevine soyutlamak için iyi bir neden (bunun dışında bir işlevi tanımlamadan işlev işaretçileri olamaz).

Yani bu lambdaları düzeltmek için tanıtıldı. Lambdalar işlev işaretçiler değil, işlev nesneleridir. Temelde aşağıdakileri yapan [x1, x2](y1,y2){bla} kodu gibi bir lambda değişmezi kullanılırsa:

  1. İki üye değişkeni (x1 Ve x2) Ve bağımsız değişkenleri olan bir operator() içeren bir sınıf tanımlayın (y1 Ve y2) Ve gövde bla.
  2. x1 Ve x2 Üye değişkenlerini şu anda kapsamdaki x1 Ve x2 Değişkenlerine ayarlayarak sınıfın bir örneğini oluşturun.

Bu nedenle lambdalar fonksiyon nesneleri gibi davranırlar, ancak lambda'yı kullanmak için üretilen sınıfa lambda kullanmaktan başka bir şekilde erişemezsiniz. Sonuç olarak, functorları argüman olarak kabul eden herhangi bir fonksiyon (temel olarak standart kütüphanedeki C olmayan herhangi bir fonksiyon anlamına gelir), lambdaları kabul eder, ancak sadece fonksiyon işaretleyicilerini kabul eden herhangi bir fonksiyon kabul etmez.

43
sepp2k

Temel olarak, lambda işlevleri "anında" oluşturduğunuz işlevlerdir. C++ 1x'te fonksiyonel programlama desteğini geliştirmek için kullanılabilirler:

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

Bu kabaca buna benzer bir kodla sonuçlanır:

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

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

Eğer ihtiyacın varsa some_functor sadece bu std::for_each() çağrısı için, o zaman lambda fonksiyonunun üzerinde birçok avantajı vardır:

  • döngüde yapılanlar, döngü işlevinin çağrıldığı yerde belirtilir
  • bazı kazan plakası kodunu yazmanızı önler
  • herkesin neye ihtiyaç duyduğunu merak eden koda bakmasını sağlayan bazı ad alanı kapsamında etrafta functor yok
18
sbi

Bir lambda işlevi, anonim bir işlev için başka bir isimdir - esasen adı olmayan bir işlev.

Genellikle bu işlevi yalnızca bir kez kullanmanız gereken dillerde kullanırsınız. Örneğin,

def add(a, b)
  return a+b

ve daha sonra bu işlevi böyle bir işleve aktarmak

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

Bir lambda ile

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