Bu enteresan bir tartışma. @ Flodel'in örneğinin mükemmel olduğunu düşünüyorum. Bununla birlikte, işlevsel bir kodlama stili yerine return
bir 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, return
yer dışında; foo
daha ç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 bar
bu kadar müsait return
tabloları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.
}
while
O 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ı return
ihmal edilebilir, ancak return
iş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 return
muhtemelen yardımcı olmaz, ancak onları işlevsel bir stile yönlendirmek işe yarayacaktır.
@Paul return
zorunlu 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 return
ifade gerektirir . Ancak, işlevinizi işlevsel bir tarzda programladıysanız, büyük olasılıkla yalnızca bir return
deyiminiz olur: işlevinizin sonunda.
Başka bir StackOverflow gönderisinden bir örnek kullanarak, TRUE
belirli bir değerdeki tüm değerlerin x
tek 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 ?ifelse
kesinlikle ilginç, ancak işlevin kullanımını caydırmaya çalıştıklarını sanmıyorum. Aslında, ifelse
fonksiyonları 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 foo
herhangi bir uzunlukta çalışır a
. Aslında, a
bir matris olduğunda bile işe yarayacaktır . Değeri, test
vektörleştirmeye yardımcı olan bir özellikle aynı şekilde döndürmek , sorun değil.
return
son örnekte bile gereksizdir. Kaldırmakreturn
biraz daha hızlı olabilir, ancak bence bunun R'nin işlevsel bir programlama dili olduğu söyleniyor.