ทำไมคำหลัก rec จำเป็นใน F #


28

ใน F # มีความจำเป็นต้องใช้recคำหลัก ใน Haskell ไม่จำเป็นต้องบอกอย่างชัดเจนว่าฟังก์ชั่นที่ให้มานั้นเรียกซ้ำหรือไม่

ด้วยบทบาทของการเรียกซ้ำในการเขียนโปรแกรมเชิงฟังก์ชันการออกแบบ F # ดูเหมือนจะค่อนข้างแปลกสำหรับฉัน เป็นการตัดสินใจออกแบบภาษาที่ดีหรือมีเหตุผลทางประวัติศาสตร์หรือมีข้อ จำกัด ในการใช้งานเท่านั้น

คำตอบ:


16

มีความแตกต่างโดยธรรมชาติใน Haskell และความหมาย F # ใน Haskell การเรียกใช้ฟังก์ชันจะไม่ทำการคำนวณจริงใด ๆ แต่จัดสรรวัตถุฮีปที่รู้จักในชื่อ 'thunk' มันก็โอเคอย่างสมบูรณ์แบบสำหรับอันที่จะมีลิงค์ไปยังตัวมันเองหรืออันอีกอัน อย่างไรก็ตามใน F # การเรียกใช้ฟังก์ชันเป็นการโทรจริงทำให้การแสดงออกlet x = 1 : 2 : x in xไม่ถูกต้องเนื่องจากต้องxสร้างก่อน1 : 2 : xจึงจะถูกสร้างขึ้น อย่างไรก็ตามมันยังคงเป็นคำจำกัดความที่สมเหตุสมผลมากขึ้นหรือน้อยลงสำหรับรายการที่ไม่มีที่สิ้นสุดวิธีที่จะกำหนดมันควรมีอยู่ recอยู่ที่นี่รากสำหรับ หากคุณต้องการมากกว่านี้ให้ค้นหาและอ่านความหมายเชิงปฏิบัติการสำหรับ SML และ Haskell ซึ่งแตกต่างกัน


2
AFAIK, Haskell ไม่มีจุดมุ่งหมายในการปฏิบัติการ
dan_waterworth

@dan_waterworth เป็นไปไม่ได้ที่จะรวบรวมโดยไม่มีการกำหนดความหมายของการปฏิบัติการ
permeakra

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

6
@dan_waterworth ในทางปฏิบัติมีเพียงหนึ่งการใช้งานและมาตรฐานของภาษา Haskell: ghc, และมีเพียงหนึ่ง F # มาตรฐาน: การใช้งานของ Microsoft ในทางทฤษฎีคุณอาจพูดถูก แต่การฝึกฝนนั้นแตกต่างไปจากเดิมอย่างสิ้นเชิง
permeakra

19

คำถามนี้ได้รับการตอบใน SOและรวมถึงประวัติความเป็นมาที่แข็งแกร่งว่าทำไมจึงใช้ "rec"

นี่คือคำพูดที่สำคัญสำหรับลูกหลาน:

ฟังก์ชันจะไม่เรียกซ้ำโดยค่าเริ่มต้นในตระกูลภาษา CAML ภาษาฝรั่งเศส (รวมถึง OCaml) ตัวเลือกนี้ทำให้การกำหนดฟังก์ชัน (และตัวแปร) เป็น supercede ง่ายขึ้นโดยใช้การอนุญาตในภาษาเหล่านั้นเนื่องจากคุณสามารถอ้างถึงคำจำกัดความก่อนหน้านี้ภายในเนื้อหาของคำจำกัดความใหม่ F # สืบทอดไวยากรณ์นี้จาก OCaml


12

การเรียกซ้ำจะletกำหนดความหมายที่ซับซ้อนกว่าอย่างมาก ดังนั้นเพื่อประโยชน์ของความเรียบง่ายและการออกแบบภาษาสะอาด, มีเหตุผลที่ดีที่จะมีทั้งสองเพียงเช่นเดียวกับที่มีการแยกจากกันlet, let*และletrecในโครงการ

ง่ายเทียบเท่ากับlet x = y in z ((fun x -> z) y)การเรียกซ้ำซ้ำนั้นซับซ้อนกว่ามากและอาจเกี่ยวข้องกับการใช้ combinator แบบจุดคงที่

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