İşlevsel programlamada fark yaratan nedir?
İşlevsel programlama ilke olarak bildiricidir . Söyleyecek Ne senin sonuç yerine ise nasıl bunu hesaplamak için.
Snippet'inizin gerçekten işlevsel uygulanmasına bir göz atalım. Haskell'de şöyle olurdu:
predsum pred numbers = sum (filter pred numbers)
Sonucun ne olduğu açık mı ? Oldukça, yüklemi karşılayan sayıların toplamıdır. Nasıl hesaplanır? Umurumda değil, derleyiciye sor.
Muhtemelen sum
vefilter
işlevini bir hile önemli değildir. O zaman bu yardımcılar olmadan uygulayalım (en iyi yol önce onları uygulamak olsa da).
Kullanılmayan "Fonksiyonel Programlama 101" çözümü sum
özyineleme ile:
sum pred list =
case list of
[] -> 0
h:t -> if pred h then h + sum pred t
else sum pred t
Tek işlev çağrısı açısından sonucun ne olduğu hala açıktır . Ya 0
, ya da recursive call + h or 0
bağlı pred h
. Sonuç oldukça hızlı olmasa bile yine de oldukça düzdür (biraz pratikle bu gerçekten bir for
döngü gibi okunur ).
Bunu sürümünüzle karşılaştırın:
public int Sum(Func<int,bool> predicate, IEnumerable<int> numbers){
int result = 0;
foreach(var item in numbers)
if (predicate(item)) result += item;
return result;
}
Sonuç nedir? Anlıyorum: Tek return
açıklamada, buraya şaşırtır: return result
.
Ama nedir result
? int result = 0
? Doğru görünmüyor. Daha sonra bununla bir şey yapıyorsun 0
. Tamam, sen ekleitem
ona s . Ve bunun gibi.
Tabii ki, çoğu programcı için bu, böyle basit bir funciton'da neler olduğu oldukça açıktır, ancak ekstra bir return
ifade ekler ve aniden izlemek zorlaşır. Tüm kod, okuyucunun anlaması için nasıl ve ne bırakılacağıyla ilgilidir - bu açıkça çok zorunlu bir stildir .
Değişkenler ve döngüler yanlış mı?
Hayır.
Onlar tarafından daha kolay açıklanabilecek birçok şey ve değişebilir durumun hızlı olmasını gerektiren birçok algoritma vardır. Ancak değişkenler doğası gereği zorunludur, neyin yerine nasıl olduğunu açıklar ve birkaç satır sonra veya birkaç döngü yinelemesinden sonra değerlerinin ne olabileceğine dair çok az tahmin verir. Döngüler genellikle mantıklı olmak için devlete ihtiyaç duyarlar ve bu nedenle de doğası gereği zorunludurlar.
Değişkenler ve döngüler basitçe işlevsel programlama değildir.
özet
Davranışsal olarak klasik programlama, bir paradigmadan biraz daha fazla stil ve yararlı bir düşünme şeklidir. Saf işlevlerin güçlü tercihi bu düşünce yapısındadır, ancak aslında sadece küçük bir kısmıdır.
Çoğu yaygın dil bazı fonksiyonel yapıları kullanmanıza izin verir. Örneğin Python'da aşağıdakiler arasından seçim yapabilirsiniz:
result = 0
for num in numbers:
if pred(result):
result += num
return result
veya
return sum(filter(pred, numbers))
veya
return sum(n for n in numbers if pred(n))
Bu işlevsel ifadeler bu tür problemlere iyi uyum sağlar ve sadece kodu kısaltır (ve daha kısa iyidir ). Düşüncesizce kodu onlarla değiştirmemelisiniz, ancak uyduklarında neredeyse her zaman daha iyi bir seçimdir.
item
döngüde mutasyon geçirdiğinde yan etkisi vardır .