Bu enteresan bir tartışma. @ Flodel'in örneğinin mükemmel olduğunu düşünüyorum. Bununla birlikte, işlevsel bir kodlama stili yerine returnbir zorunluluk kullandığınızda mantıklı olan benim açımdan (ve bir yorumda @koshke'den bahsettiğini) açıkladığını düşünüyorum .
Bu noktayı suçlamak değil, ama şöyle yazmıştım foo:
foo = function() ifelse(a,a,b)
İşlevsel bir stil, değerini depolamak gibi durum değişikliklerini önler output. Bu tarzda, returnyer dışında; foodaha çok matematiksel bir işleve benziyor.
@Flodel ile aynı fikirdeyim: Karmaşık bir boolean değişken sistemi kullanmak bar, daha az net ve anlamsız olurdu return. Ne yapar barbu kadar müsait returntabloların bir zorunluluk tarzda yazılmış olmasıdır. Gerçekten de, boole değişkenleri fonksiyonel bir tarzda kaçınılan "durum" değişikliklerini temsil eder.
barİşlevsel tarzda yeniden yazmak gerçekten zordur , çünkü sadece sahte koddur, ancak fikir şu şekildedir:
e_func <- function() do_stuff
d_func <- function() ifelse(any(sapply(seq(d),e_func)),2,3)
b_func <- function() {
do_stuff
ifelse(c,1,sapply(seq(b),d_func))
}
bar <- function () {
do_stuff
sapply(seq(a),b_func) # Not exactly correct, but illustrates the idea.
}
whileO devlet değişiklikleri ile kontrol edilir, çünkü döngü, yeniden yazmak en zor olurdu a.
Bir çağrının neden olduğu hız kaybı returnihmal edilebilir, ancak returnişlevsel bir tarzda kaçınarak ve yeniden yazarak elde edilen verimlilik genellikle çok yüksektir. Yeni kullanıcılara kullanmayı bırakmalarını söylemek returnmuhtemelen yardımcı olmaz, ancak onları işlevsel bir stile yönlendirmek işe yarayacaktır.
@Paul returnzorunlu bir tarzda gereklidir, çünkü genellikle bir döngüdeki farklı noktalardan işlevden çıkmak istersiniz. İşlevsel bir tarzda döngüler kullanılmaz ve bu nedenle gerekmez return. Tamamen işlevsel bir tarzda, son çağrı neredeyse her zaman istenen dönüş değeridir.
Python'da işlevler bir returnifade gerektirir . Ancak, işlevinizi işlevsel bir tarzda programladıysanız, büyük olasılıkla yalnızca bir returndeyiminiz olur: işlevinizin sonunda.
Başka bir StackOverflow gönderisinden bir örnek kullanarak, TRUEbelirli bir değerdeki tüm değerlerin xtek bir uzunluğu varsa döndürülen bir işlev istediğimizi varsayalım . İki stil kullanabiliriz:
# Procedural / Imperative
allOdd = function(x) {
for (i in x) if (length(i) %% 2 == 0) return (FALSE)
return (TRUE)
}
# Functional
allOdd = function(x)
all(length(x) %% 2 == 1)
İşlevsel bir tarzda, döndürülecek değer doğal olarak işlevin uçlarına düşer. Yine, daha çok matematiksel bir fonksiyona benziyor.
@Genişler Ana hatlarıyla verilen uyarılar ?ifelsekesinlikle ilginç, ancak işlevin kullanımını caydırmaya çalıştıklarını sanmıyorum. Aslında, ifelsefonksiyonları otomatik olarak vektörleme avantajına sahiptir. Örneğin, biraz değiştirilmiş bir sürümünü düşünün foo:
foo = function(a) { # Note that it now has an argument
if(a) {
return(a)
} else {
return(b)
}
}
Bu işlev length(a)1 olduğunda iyi çalışır . Ancak foo, birifelse
foo = function (a) ifelse(a,a,b)
Şimdi fooherhangi bir uzunlukta çalışır a. Aslında, abir matris olduğunda bile işe yarayacaktır . Değeri, testvektörleştirmeye yardımcı olan bir özellikle aynı şekilde döndürmek , sorun değil.
returnson örnekte bile gereksizdir. Kaldırmakreturnbiraz daha hızlı olabilir, ancak bence bunun R'nin işlevsel bir programlama dili olduğu söyleniyor.