Lambda matematiği 30'lu yıllarda Alonzo Kilisesi tarafından icat edilen bir hesaplama modelidir. Çoğu işlevsel programlama dilinin sözdizimi ve anlambilimi, doğrudan veya dolaylı olarak lambda matematiğinden ilham almaktadır.
Lambda matematiğinin en temel haliyle iki işlemi vardır: Soyutlama (adsız bir fonksiyon oluşturma) ve uygulama (bir fonksiyon uygulama). Soyutlama λ operatörü kullanılarak gerçekleştirilir ve bu da lambda hesabına adını verir.
- Lambda ifadeleri
- Lambda fonksiyonları
Anonim işlevler genellikle "lambda", "lambda işlevler" veya "lambda ifadeler" olarak adlandırılır, çünkü yukarıda belirttiğim gibi λ, lambda hesabında anonim işlevler oluşturmanın simgesidir (ve kelime lambda
birçok lispta anonim işlevler oluşturmak için kullanılır) tabanlı aynı dilde).
Bu yaygın olarak kullanılan bir terim değildir, ancak anonim işlevler kullanarak programlama veya daha yüksek dereceli işlevler kullanarak programlama anlamına gelir.
C ++ 0x 'deki lambdalar, motivasyonları ve fonksiyon göstergeleri ile nasıl ilişkili oldukları hakkında biraz daha fazla bilgi (bunun çoğu zaten bildiklerinizin bir tekrarı olabilir, 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 var olan fonksiyon işaretçileri, örneğin bir sıralama fonksiyonuna bir karşılaştırma fonksiyonunu geçmek için oldukça kullanışlıdır. Bununla birlikte, yararlarının sınırları vardır:
Örneğin, bir vektörün vektörünü i
her bir vektörün th elemanına göre sıralamak istiyorsanız ( i
çalışma zamanı parametresidir), bunu bir işlev işaretçisiyle çözemezsiniz. İki vektörü i
th elemanlarıyla karşılaştıran bir fonksiyonun üç argüman alması gerekir ( i
ve iki vektör), ancak sıralama fonksiyonu iki argüman alan bir fonksiyona ihtiyaç duyar. İhtiyacımız olan şey, argümanı i
sıralama fonksiyonuna aktarmadan önce fonksiyona bir argüman sağlamanın bir yoludur , ancak bunu düz C fonksiyonlarıyla yapamayız.
Bunu çözmek için, C ++ "fonksiyon nesneleri" veya "işlev" kavramını ortaya koydu. Bir işlev, temelde bir operator()
yöntemi olan bir nesnedir . Şimdi CompareByIthElement
argümanı i
yapıcı argüman olarak alan ve sonra argüman olarak karşılaştırılacak iki vektörü operator()
metodla karşılaştıran bir sınıf tanımlayabiliriz . Bir vektör vektörünü i
th öğesine göre sıralamak için şimdi argüman olarak bir CompareByIthElement
nesne oluşturabilir i
ve sonra bu nesneyi sıralama işlevine geçirebiliriz.
İşlev nesneleri yalnızca nesneler olduğundan ve teknik olarak işlevler olmadığından (onlar gibi davranmak zorunda olsalar bile), işlev işaretçisini işlev nesnesine işaret edemezsiniz (elbette işlev nesnesine işaretçi olabilir, ancak gibi bir tür olurdu CompareByIthElement*
ve bu nedenle bir işlev işaretçisi olamazdı).
İşlevleri argüman olarak alan C ++ standart kütüphanesindeki işlevlerin çoğu, işlev işaretçilerinin yanı sıra işlev nesneleriyle çalışabilmeleri için şablonlar kullanılarak tanımlanır.
Şimdi lambdas'a:
Bir i
öğeyi sıralamak için yalnızca bir kez kullanacaksanız , th öğesiyle karşılaştırılacak bir sınıfı tanımlamak 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 düşük düzeydedir; mantığı kendi işlevine soyutlamak için iyi bir neden (bunun dışında bir işlev tanımlamaksızın işlev işaretçilerine sahip olamamanız).
Böylece bu lambdaları düzeltmek için tanıtıldı. Lambdalar fonksiyon işaretçisi değil fonksiyon nesnesidir. Bir lambda kullanırsanız [x1, x2](y1,y2){bla}
, temel olarak aşağıdakileri yapan hazır kod benzer bir kod üretilir:
- İki üye değişkenine (
x1
ve x2
) ve bir operator()
de argümanlara ( y1
ve y2
) ve gövdeye sahip olan bir sınıf tanımlayın bla
.
- Üye değişkenleri ayarlayarak, sınıfının bir örneğini oluşturun
x1
ve x2
değişkenlerin değerlerine x1
ve x2
halen kapsamında.
Böylece lambdalar, fonksiyon nesneleri gibi davranırlar, ancak lambda kullanmak dışında bir lambda uygulamak için oluşturulan sınıfa erişemezsiniz. Sonuç olarak, fonk- siyonları 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şaretçilerini kabul eden herhangi bir fonksiyon kabul etmez.