นี่คือการสนทนาที่น่าสนใจ ฉันคิดว่าตัวอย่างของ @ flodel นั้นยอดเยี่ยม แต่ผมคิดว่ามันแสดงให้เห็นถึงจุดของฉัน (และ @koshke กล่าวนี้ในความคิดเห็น) ที่return
ทำให้รู้สึกเมื่อคุณใช้ความจำเป็นแทนการทำงานรูปแบบการเข้ารหัส
ไม่ต้องปฏิเสธประเด็นนี้ แต่ฉันจะเขียนใหม่foo
เช่นนี้:
foo = function() ifelse(a,a,b)
output
สไตล์การทำงานหลีกเลี่ยงการเปลี่ยนแปลงสถานะเช่นเดียวกับการจัดเก็บค่าของ ในสไตล์นี้return
อยู่นอกสถานที่; foo
ดูเหมือนฟังก์ชั่นทางคณิตศาสตร์มากขึ้น
ผมเห็นด้วยกับ @flodel: การใช้ระบบซับซ้อนของตัวแปรบูลีนในจะมีความชัดเจนน้อยลงและไม่มีจุดหมายเมื่อคุณมีbar
return
สิ่งที่ทำให้bar
คล้อยตามreturn
งบก็คือมันถูกเขียนในรูปแบบที่จำเป็น แท้จริงแล้วตัวแปรบูลีนเป็นตัวแทนของการเปลี่ยนแปลง "สถานะ" ที่หลีกเลี่ยงในรูปแบบการทำงาน
มันยากมากที่จะเขียนbar
ในรูปแบบการใช้งานจริง ๆ เพราะมันเป็นรหัสปลอม แต่ความคิดนั้นเป็นดังนี้:
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
a
การสูญเสียความเร็วที่เกิดจากการโทรหาreturn
มีน้อยมาก แต่ประสิทธิภาพที่ได้รับจากการหลีกเลี่ยงreturn
และการเขียนใหม่ในสไตล์การใช้งานมักเป็นเรื่องใหญ่โต การบอกให้ผู้ใช้รายใหม่หยุดใช้return
อาจจะไม่ช่วย แต่การชี้แนะผู้ใช้ให้เข้ากับรูปแบบการใช้งานจะเป็นการตอบแทน
@Paul return
มีความจำเป็นในรูปแบบที่จำเป็นเพราะคุณมักต้องการออกจากฟังก์ชั่นที่จุดต่าง ๆ ในลูป return
สไตล์การทำงานไม่ได้ใช้ลูปและดังนั้นจึงไม่จำเป็นต้อง ในรูปแบบที่ใช้งานได้จริงการโทรครั้งสุดท้ายเกือบจะเป็นค่าตอบแทนที่ต้องการทุกครั้ง
ใน Python ฟังก์ชั่นต้องการreturn
คำสั่ง อย่างไรก็ตามหากคุณตั้งโปรแกรมฟังก์ชั่นของคุณในสไตล์การใช้งานคุณจะมีreturn
คำสั่งเพียงคำสั่งเดียว: ในตอนท้ายของฟังก์ชัน
ใช้ตัวอย่างจากโพสต์ StackOverflow อื่นให้เราบอกว่าเราต้องการฟังก์ชั่นที่คืนค่าTRUE
ถ้าค่าทั้งหมดในค่าที่กำหนดx
มีความยาวคี่ เราสามารถใช้สองรูปแบบ:
# 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)
ในสไตล์การใช้งานค่าที่ส่งคืนจะตกหล่นที่ส่วนท้ายของฟังก์ชันตามธรรมชาติ อีกครั้งดูเหมือนว่าฟังก์ชันทางคณิตศาสตร์
@ GSee คำเตือนที่ระบุไว้ใน?ifelse
นั้นมีความน่าสนใจ แต่ฉันไม่คิดว่าพวกเขากำลังพยายามที่จะห้ามการใช้ฟังก์ชั่น ในความเป็นจริงifelse
มีข้อดีของฟังก์ชั่นเวกเตอร์อัตโนมัติ ตัวอย่างเช่นพิจารณาเวอร์ชันที่แก้ไขเล็กน้อยของfoo
:
foo = function(a) { # Note that it now has an argument
if(a) {
return(a)
} else {
return(b)
}
}
ฟังก์ชั่นนี้ใช้งานได้ดีเมื่อlength(a)
เป็น 1 แต่ถ้าคุณเขียนใหม่foo
ด้วยifelse
foo = function (a) ifelse(a,a,b)
ตอนนี้ทำงานอยู่กับระยะเวลาของการใดfoo
ๆ a
ในความเป็นจริงมันจะทำงานได้แม้a
เป็นเมทริกซ์ การคืนค่าเป็นรูปร่างเดียวกับที่test
เป็นคุณลักษณะที่ช่วยในการทำให้เป็น vectorization ไม่ใช่ปัญหา
return
ไม่จำเป็นแม้แต่ในตัวอย่างสุดท้าย การนำออกreturn
อาจทำให้เร็วขึ้นเล็กน้อย แต่ในมุมมองของฉันนี่เป็นเพราะ R ถูกกล่าวว่าเป็นภาษาที่ใช้ในการเขียนโปรแกรม