ฟังก์ชั่นการเขียนโปรแกรมเทียบกับ OOP [ปิด]


93

ฉันได้ยินมาหลายเรื่องเกี่ยวกับการใช้ภาษาที่ใช้งานได้เช่น Haskell เป็นต้น ข้อดีและข้อเสียของการเขียนโปรแกรมเชิงฟังก์ชันกับการเขียนโปรแกรมเชิงวัตถุคืออะไร


27
หนึ่งไม่ปฏิเสธอีก
mbq

1
@mbq ฉันเข้าใจว่าพวกเขาไม่ได้มีความเป็นเอกเทศร่วมกัน แต่ฉันแค่อยากจะลองเข้าใจความแตกต่างของสองแนวทางนี้ให้ดีขึ้น
GSto

เป็นคำถามที่ดีมาก ฉันก็สงสัยเกี่ยวกับเรื่องนี้เช่นกัน
JohnFx

ฟังก์ชั่นการเขียนโปรแกรมและการเขียนโปรแกรมเชิงวัตถุเป็นมุมฉากซึ่งกันและกัน คุณสามารถมีทั้งในภาษาเดียวกัน ตัวอย่าง: Scala, F #, OCaml ฯลฯ คุณอาจหมายถึงฟังก์ชั่นการใช้งานและความจำเป็นตามที่โจนาสแนะนำ ?
missingfaktor

4
คำตอบที่แท้จริงคือ - ไม่มี "กับ" ระหว่างพวกเขา ตรวจสอบคำถามนี้ที่ StackOverflow
missingfaktor

คำตอบ:


67

ฉันจะบอกว่ามันเป็นหน้าที่ Programmingเทียบกับการเขียนโปรแกรมจำเป็น

ความแตกต่างที่ใหญ่ที่สุดคือการเขียนโปรแกรมเป็นเรื่องเกี่ยวกับความจำเป็นในการควบคุมการไหลในขณะที่ฟังก์ชั่นการเขียนโปรแกรมเป็นเรื่องเกี่ยวกับการไหลของข้อมูล อีกวิธีที่จะบอกว่ามันคือการเขียนโปรแกรมการทำงานใช้เพียงการแสดงออกในการเขียนโปรแกรมที่จำเป็นทั้งการแสดงออกและคำสั่งจะใช้

ตัวอย่างเช่นในตัวแปรการเขียนโปรแกรมที่จำเป็นและลูปเป็นเรื่องธรรมดาเมื่อจัดการสถานะในขณะที่ในการเขียนโปรแกรมการทำงานรัฐจะจัดการผ่านการส่งพารามิเตอร์ซึ่งหลีกเลี่ยงผลข้างเคียงและการกำหนด

หลอกหลอกรหัสสำหรับฟังก์ชั่นสำหรับการคำนวณผลรวมของรายการ (ผลรวมจะถูกเก็บไว้ในตัวแปร):

int sumList(List<int> list) {
    int sum = 0;
    for(int n = 0; n < list.size(); n++) {
        sum = sum + list.get(n);
    }

    return sum;
}

ฟังก์ชันหลอกรหัสสำหรับฟังก์ชั่นเดียวกัน (ผลรวมจะถูกส่งเป็นพารามิเตอร์):

fun sumList([], sum) = sum
 |  sumList(v::lst, sum) = sumList(lst, v+sum)

ฉันแนะนำงานนำเสนอTaming Effects พร้อมฟังก์ชั่นการเขียนโปรแกรมโดยSimon Peyton-Jonesสำหรับการแนะนำแนวคิดการทำงานที่ดี


12
คุณควรพูดถึงว่าเวอร์ชั่นฟังก์ชั่นนี้ทำงานแบบซ้ำและปรับให้เหมาะสมเพื่อหลีกเลี่ยงการโอเวอร์โฟลว์แบบสแต็ก (บางคนอาจเห็นการเรียกซ้ำและคิดว่าการเขียนโปรแกรมใช้งานไม่ดีเพราะมัน)
ทางเลือก

3
+1 สำหรับการอธิบายลักษณะที่สำคัญที่สุดของความจำเป็นกับการทำงาน: การควบคุมการไหลและการไหลของข้อมูล สิ่งหนึ่งที่ฉันต้องเพิ่มก็คือกระบวนทัศน์การทำงานและกระบวนทัศน์ OO นั้นไม่ได้เกิดขึ้นพร้อมกัน คุณสามารถใช้กระบวนทัศน์ OO เพื่อสร้างแบบจำลองว่าวัตถุ (ข้อมูล) โต้ตอบและกระบวนทัศน์การทำงานเพื่อแปลง (จัดการ) วัตถุนั้นอย่างไร
Lie Ryan

1
ที่น่าสนใจคือคุณสามารถสร้างโมเดล data-as-control และ control-as-data รวมถึง intermix FP สามารถใช้ลูกศรและฟังก์ชั่นการสั่งซื้อครั้งแรกเพื่อส่งผังการควบคุมไปรอบ ๆ และจัดการกับมันเช่นเดียวกับข้อมูล OOP ใช้รูปแบบการออกแบบที่หลากหลายเพื่อใช้วัตถุสำหรับเปลี่ยนการควบคุมการไหล
CodexArcanum

ฉันคิดว่ามันก็น่าสังเกตว่าความแตกต่างที่สำคัญไม่ใช่ว่าคุณเขียนโปรแกรมเดียวกัน แต่คุณใช้วิธีลูปแบบเรียกซ้ำ มันใหญ่กว่านั้น
sara

ตัวอย่างการทำงานของคุณใช้ประโยชน์จากการจับคู่รูปแบบพารามิเตอร์ นั่นไม่ได้เป็นเอกสิทธิ์ของการเขียนโปรแกรมที่ใช้งานได้ แต่ฟังก์ชันการทำงานที่คล้ายกันสามารถใช้ monads และโครงสร้างที่คล้ายกันได้โดยไม่จำเป็นต้องกำหนดอัลกอริธึมซ้ำ ๆ เป็นอัลกอริธึมวนซ้ำ
Dai

16

ฟังก์ชั่นการเขียนโปรแกรมจะขึ้นอยู่กับรูปแบบการประกาศและมีรากมาจากแคลคูลัสแลมบ์ดา มันมีแนวคิดที่ยอดเยี่ยมมากมายซึ่งสามารถยืมได้จากภาษาที่จำเป็นมากขึ้นเช่น C ++ และ C #

ตัวอย่างบางส่วนประกอบด้วยความโปร่งใสในการอ้างอิง, ฟังก์ชั่นแลมบ์ดา, ฟังก์ชั่นชั้นหนึ่ง, การประเมินขี้เกียจและกระตือรือร้นและความไม่สามารถเปลี่ยนแปลงได้

หากไม่มีอะไรอื่นการเรียนรู้การเขียนโปรแกรมฟังก์ชั่นการใช้งานมีประโยชน์สำหรับแนวคิดที่มี มันจะเปลี่ยนวิธีการเขียนโปรแกรมและคิดเกี่ยวกับการเขียนโปรแกรม และฉันเดาว่าในอนาคตการตั้งโปรแกรมการทำงานจะมีความสำคัญเท่ากับการเขียนโปรแกรมเชิงวัตถุ

ในการเริ่มต้นที่คุณสามารถเลือกที่จะใช้ภาษาทำงานบริสุทธิ์เช่น Haskell, หรือคุณสามารถใช้หนึ่งไฮบริดเช่นF #

มหาวิทยาลัยที่ดีส่วนใหญ่จะครอบคลุมการเขียนโปรแกรมที่ใช้งานได้และถ้าคุณไปโรงเรียนฉันขอแนะนำให้คุณเรียนหลักสูตรนั้น


ข้อดีและข้อเสียของการเขียนโปรแกรมเชิงฟังก์ชันกับการเขียนโปรแกรมเชิงวัตถุคืออะไร

การเขียนโปรแกรมเชิงวัตถุนั้นดีเพราะช่วยให้คุณสามารถจำลองปัญหาที่ซับซ้อนของคุณเป็นลำดับชั้นเพื่อให้คุณสามารถทำให้ปัญหาง่ายขึ้น แต่มันจะยากมากเมื่อคุณเริ่มพิจารณาการเขียนโปรแกรมแบบหลายเธรดในขณะที่ใช้วัตถุที่ไม่แน่นอน ในกรณีเช่นนี้คุณจำเป็นต้องใช้งานการซิงโครไนซ์วัตถุอย่างหนักและเป็นไปไม่ได้ที่จะทำให้แอพพลิเคชั่นขนาดใหญ่สมบูรณ์แบบ

นั่นคือสิ่งที่การเขียนโปรแกรมฟังก์ชั่นเข้ามาเพราะสิ่งต่าง ๆ เช่นการเขียนโปรแกรมฟังก์ชั่นที่ไม่สามารถเปลี่ยนแปลงได้ช่วยให้โปรแกรมแบบหลายเธรดง่ายขึ้น มันทำให้แทบจะเป็นเรื่องง่ายที่จะขนานอะไรบางอย่างเมื่อคุณรู้ว่าการป้อนข้อมูล X ให้กับฟังก์ชั่นนั้นจะส่งออก Y เสมอนอกจากนี้คุณรู้ว่าตัวแปร (หรือค่าในการเขียนโปรแกรมการทำงาน) ไม่สามารถเปลี่ยนการใช้งานกลางจากเธรดอื่น


2
เพื่อความชัดเจน Scheme ไม่ได้หมายถึงภาษาที่ใช้งานได้จริง
Jonathan Sterling

5
ย่อหน้าสุดท้ายของคุณที่สองคือ bs อย่างสมบูรณ์ OO ไม่ก่อให้เกิดปัญหาใด ๆ ในการทำงานแบบมัลติเธรด คุณดูเหมือนจะสับสนเกี่ยวกับการเขียนโปรแกรมที่จำเป็นด้วยการเขียนโปรแกรมเชิงวัตถุ เป็นอย่างนั้นเหรอ?
missingfaktor

5
@missingfaktor: ไม่ฉันไม่ได้สับสนแนวคิด โดยทั่วไปวัตถุจะมี accessors ตัวดัดแปลงข้อมูลสมาชิกและฟังก์ชันสมาชิก ใช่ไม่ใช่วัตถุทุกตัวที่จำเป็นต้องมีตัวดัดแปลงและคุณสามารถนำไปใช้เป็นสิ่งที่ไม่เปลี่ยนรูปได้ แต่ถ้าคุณดูโปรแกรม OO โดยพลการมันจะมีวัตถุหลายอย่างที่มีตัวดัดแปลงและยังคงถูกใช้โดยหลายเธรด เช่นในกระบวนทัศน์ OOP มันค่อนข้างยากที่จะมีทุกอย่างที่ไม่เปลี่ยนรูป
Brian R. Bondy

คุณควรอ่านคำตอบสำหรับคำถามนี้: stackoverflow.com/questions/3949618/fp-and-oo-orthogonal/ …
missingfaktor

ตรวจสอบคำตอบของ Frank Shearar ได้ที่นี่: programmers.stackexchange.com/questions/12423/…
missingfaktor

8

(คำตอบนี้ดัดแปลงจากคำตอบของคำถามปิดที่ StackOverflow )

หนึ่งในความแตกต่างใหญ่ระหว่างฟังก์ชั่นการเขียนโปรแกรมและการเขียนโปรแกรมเชิงวัตถุคือแต่ละอันนั้นดีกว่าในการพัฒนาซอฟต์แวร์ประเภทต่าง ๆ :

  • ภาษาเชิงวัตถุนั้นดีเมื่อคุณมีชุดการดำเนินการที่แน่นอนในสิ่งต่าง ๆและเมื่อโค้ดของคุณวิวัฒนาการคุณจะต้องเพิ่มสิ่งใหม่ ๆ เป็นหลัก สิ่งนี้สามารถทำได้โดยการเพิ่มคลาสใหม่ซึ่งใช้วิธีการที่มีอยู่และคลาสที่มีอยู่จะถูกทิ้งให้อยู่คนเดียว

  • ภาษาที่ใช้งานได้ดีเมื่อคุณมีชุดของสิ่งต่าง ๆคง ที่และเมื่อโค้ดของคุณวิวัฒนาการคุณจะต้องเพิ่มการปฏิบัติการใหม่ในสิ่งที่มีอยู่เป็นหลัก สิ่งนี้สามารถทำได้โดยการเพิ่มฟังก์ชั่นใหม่ซึ่งคำนวณกับชนิดข้อมูลที่มีอยู่และฟังก์ชั่นที่มีอยู่จะถูกทิ้งให้อยู่คนเดียว

เมื่อวิวัฒนาการไปในทางที่ผิดคุณมีปัญหา:

  • การเพิ่มการดำเนินการใหม่ไปยังโปรแกรมเชิงวัตถุอาจต้องมีการแก้ไขคำจำกัดความของคลาสจำนวนมากเพื่อเพิ่มวิธีการใหม่

  • การเพิ่มสิ่งใหม่ลงในโปรแกรมการใช้งานอาจจำเป็นต้องแก้ไขนิยามฟังก์ชันจำนวนมากเพื่อเพิ่มเคสใหม่

ปัญหานี้เป็นที่รู้จักกันดีมานานหลายปี ในปี 1998 ฟิล Wadler ขนานนามมันว่า "ปัญหาการแสดงออก" แม้ว่านักวิจัยบางคนคิดว่าปัญหาการแสดงออกสามารถแก้ไขได้ด้วยคุณสมบัติของภาษาเช่นมิกซ์อิน แต่ทางออกที่ได้รับการยอมรับอย่างกว้างขวางยังไม่เป็นที่นิยม


ฉันรักคำตอบของคุณคำแห่งปัญญาที่นี่ ฉันพบมันเมื่อไม่กี่เดือนที่ผ่านมาและใช้เวลาเพียง 30 นาทีโดยเฉพาะในการค้นหาเพราะฉันไม่ได้คั่นหน้ามัน คำอธิบายที่ดีที่สุดสำหรับ OOP และ FP สำหรับผู้ที่เข้าใจถึงข้อดีของการทำความเข้าใจแนวคิดมากกว่าเทคนิค บทความเกี่ยวกับปัญหาการแสดงออกก็ยอดเยี่ยมเช่นกัน ขอบคุณมากสำหรับการแบ่งปันข้อมูลเชิงลึกของคุณคำตอบของคุณอยู่ในความคิดของฉันมาก
tobiak777

4

ไม่มีจริงกับเมื่อเทียบกับ พวกเขาสามารถเสริมอย่างสมบูรณ์แบบ มีภาษา FP ซึ่งรองรับ OOP แต่ชุมชนต่างกันในวิธีที่พวกเขาจัดการโมดุล

ผู้ใช้ภาษา FP มีแนวโน้มที่จะประสบความสำเร็จแบบแยกส่วนผ่านกฎหมายทางคณิตศาสตร์ และชอบพิสูจน์เพื่อแสดงการปฏิบัติตามกฎหมายของพวกเขา

ในความจำเป็นผู้ใช้ OOP มักจะจับพฤติกรรมของวัตถุในกรณีทดสอบซึ่งสามารถเรียกใช้อีกครั้งหากวัตถุมีการเปลี่ยนแปลงและบรรลุในลักษณะนี้เป็นโมดูล

มันเป็นเพียงแง่มุมเล็ก ๆ แต่ฉันคิดว่ามันควรค่าแก่การพูดถึง


2

การเปรียบเทียบ:

คุณยื่นใบสมัครงาน คุณกรอกชื่อข้อมูลการติดต่อและประวัติการทำงานของคุณ เมื่อเสร็จแล้วคุณจะไม่มีแอปพลิเคชันว่างเปล่าอีกต่อไป

ทีนี้ลองนึกภาพแทนก่อนที่คุณจะเขียนทับมันด้วยกระดาษแก้วใส คุณเขียนชื่อของคุณ คุณเพิ่มกระดาษแก้วอีกแผ่น คุณเขียนข้อมูลผู้ติดต่อของคุณ กระดาษแก้วเพิ่มเติม คุณเขียนประวัติการทำงานของคุณ เมื่อเสร็จแล้วคุณยังคงไม่มีแอปพลิเคชันว่างเปล่า คุณมีกระดาษแก้วสามแผ่นแต่ละแผ่นมีการจับเอฟเฟกต์ของการเปลี่ยนแปลงที่ไม่ต่อเนื่องเดี่ยว

อดีต (OOP) รวบรวมความคิดของการเปลี่ยนแปลงสิ่งต่าง ๆ ในขณะที่หลัง (FP) หลีกเลี่ยงมัน ทั้งสองเป็นกระบวนทัศน์การจัดการของรัฐ ทั้งสองสามารถใช้กลยุทธ์ที่แตกต่างกันจับผลของการกรอกใบสมัครงาน OOP เปลี่ยนแปลงเครื่องมือเริ่มต้นโดยตรงในขณะที่ FP ซ้อนสิ่งที่มาก่อนที่จะมีผลกระทบต่อลักษณะของการเปลี่ยนแปลง


การเปรียบเทียบที่สวยงามขอบคุณ !! คุณจะคิด (ถ้าเป็นไปได้) ขยายการเปรียบเทียบนี้กับข้อดีและข้อเสียในวิธีการทั้งสองนี้
ราหุล Agarwal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.