ไวยากรณ์ซ้ำกันสำหรับการกำหนดฟังก์ชั่นที่มีชื่อเป็นการตัดสินใจออกแบบภาษาที่ไม่ดีหรือไม่?


9

ฉันกำลังจำลองภาษาการเขียนโปรแกรมเพื่อความสนุกสนานและไวยากรณ์ได้รับอิทธิพลอย่างมากจาก Scala - คำจำกัดความของฟังก์ชันเฉพาะ

ฉันได้พบปัญหาการออกแบบเพราะภาษาของฉันไม่ได้แยกความแตกต่างระหว่างการทำงานที่กำหนดไว้ผ่านทางdefไวยากรณ์ (วิธีการเรียน) และฟังก์ชั่นที่ไม่ระบุชื่อที่ได้รับมอบหมายให้เป็นค่า (สร้างขึ้นโดยใช้=>) - มันเอาความแตกต่างทั้งในการดำเนินงานและพฤติกรรม

ผลลัพธ์คือนิยามสองคำต่อไปนี้หมายถึงสิ่งเดียวกัน:

def square(x: Int) = x*x

val square = (x: Int) => x*x

ไม่มีเหตุผลสำหรับแบบฟอร์มหลัง (การกำหนดฟังก์ชันที่ไม่ระบุชื่อแบบทันที) ที่จะใช้ในสถานการณ์ปกติใด ๆ - เป็นไปได้ที่จะใช้แทนdefแบบฟอร์ม

จะมีไวยากรณ์ที่ซ้ำกันดังกล่าวสำหรับการกำหนดฟังก์ชั่นที่มีชื่อทำร้ายความ orthogonality ของภาษาหรือด้านการออกแบบอื่น ๆ ?

ฉันชอบโซลูชันนี้เพราะช่วยให้คำจำกัดความสั้น ๆ และใช้งานง่ายของวิธีการและฟังก์ชั่นที่มีชื่อ (ผ่านdef) และคำจำกัดความสั้น ๆ ของฟังก์ชั่นที่ไม่ระบุชื่อ (ใช้=>)

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


However, assigning existing functionsดูเหมือนว่าจะหายไปในตอนท้ายของประโยค
Izkata

1
คุณสามารถกำหนดฟังก์ชั่นวนซ้ำได้โดยใช้valสัญลักษณ์ของคุณ?
Giorgio

2
ฉันยืนยันว่านี่เป็นไปได้ใน Scala ด้วย ใน SML ไม่ใช่และคุณต้องใช้funเพื่อกำหนดฟังก์ชั่นวนซ้ำ
Giorgio

3
รูปแบบที่สองไม่ได้จริงๆโครงสร้างประโยคพิเศษวิธีการdefคือ เป็นเพียงผลข้างเคียงของความจริงที่ว่าฟังก์ชั่นที่ไม่ระบุชื่อการพูด(x : Int) => x + 1คือวัตถุและวัตถุสามารถกำหนดให้กับค่าval f = ...ได้ นักออกแบบภาษาจะต้องออกไปเพื่อไม่อนุญาตให้ใช้ไวยากรณ์ มันไม่เหมือนกับการพยายามสนับสนุนไวยากรณ์ที่แตกต่างกันสองอย่างที่ทำ (โดยประมาณ) ในสิ่งเดียวกัน
KChaloux

3
ประโยชน์ที่สำคัญของการทำอะไรมากกว่าหนึ่งทางในภาษาคือมันเป็นวิธีที่ยอดเยี่ยมในการเริ่มการอภิปรายทางศาสนาที่ไม่ก่อผลซึ่งจะหันเหความสนใจจากปัญหาที่แท้จริง (การคิด C ++ ที่นี่) .......
mattnz

คำตอบ:


3

ฉันคิดว่าการมีโครงสร้างสองอย่างที่มีความหมายเดียวกัน การทำซ้ำใด ๆ จะเพิ่มความยากลำบากในการอ่าน (และเขียน / แก้ไขโค้ด) ภาษาของคุณ การกำจัดการทำซ้ำทั้งหมดนั้นไม่สามารถหลีกเลี่ยงได้ในภาษาที่สามารถสร้างโครงสร้างตามอำเภอใจ (ตัวอย่างเช่นความเท่าเทียมกันของการทำซ้ำและการเรียกซ้ำ)

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

ในความเป็นจริงคุณสามารถใช้หลักการนี้ไม่เพียง แต่ฟังก์ชั่นที่มีชื่อ แต่กับฟังก์ชั่นใด ๆ ทำไมความแตกต่างในการกำหนดฟังก์ชั่นที่มีชื่อและฟังก์ชั่นที่ไม่ระบุชื่อ ในลิมา , fn[<arguments>: <statements>]ฟังก์ชั่นที่กำหนดไว้เสมอเช่นนี้ หากคุณต้องการที่จะ "ชื่อ" คุณสามารถกำหนดให้ตัวแปร: และถ้าคุณต้องการที่จะผ่านเข้ากับฟังก์ชั่นอื่นโดยไม่ระบุชื่อ:var x = fn[<arguments: <statements>] หากคุณต้องการให้มันยกให้มันคงที่function[fn[<arguments: <statements>]] const var x = fn[<arguments: <statements>]รูปแบบเดียวทำให้ชัดเจนว่าพวกเขาหมายถึงสิ่งเดียวกัน


ค่อนข้างน่าสนใจที่constทำให้เกิดการยก แต่มันก็สมเหตุสมผลดี ใน JS function myFuncทำให้เกิดอาการชัก แต่var myFunc =ไม่ได้ซึ่งอาจเป็นเรื่องที่เข้าใจง่ายน้อยกว่าเล็กน้อยเพราะมันทำตัวเหมือนกัน
mpen

1
@mpen ใช่จาวาสคริปต์จริงๆแล้วทำสิ่งเดียวกัน function fnName()...รูปแบบในความเป็นจริงไม่สร้างอย่างต่อเนื่องซึ่งเป็นสิ่งที่ทำให้ยกเป็นสิ่งที่ถูกต้องที่จะทำอย่างไรกับมัน Javascript ทำให้สิ่งต่าง ๆ น่าสับสนเมื่อคุณใช้แบบฟอร์มvar fn = function anotherFnName()...ตั้งแต่ที่ทำให้ชื่อanotherFnName ไม่ใช่การชักรอกแม้กระทั่งสรรพสิ่งคงที่อย่างชัดเจน
BT

2

สิ่งที่คุณโพสต์คือสกาล่าที่ถูกต้องและใช้งานได้ดี

เนื่องจากการเพิ่มเป็นสองเท่าไม่ได้ทำให้เกิดปัญหากับสกาล่า (สำหรับความรู้ของฉัน) ฉันจะบอกว่ามันจะไม่เป็นปัญหาสำหรับภาษาของคุณเช่นกัน


1
มันใช้งานได้ใน Scala ส่วนใหญ่ใช้งานได้เหมือนกัน แต่ไม่ได้หมายถึงสิ่งเดียวกัน - และหากคุณสร้างตัวอย่างที่ซับซ้อนมากขึ้น (ประเภท polymorphism ไม่สามารถใช้กับฟังก์ชันที่ไม่ระบุชื่อเช่น) - ความแตกต่างจะชัดเจนขึ้น
jcora

2

ฉันพบความแตกต่างพื้นฐานระหว่าง lambdas และdefวิธีการใน Scala - ฉันยังไม่แน่ใจว่าฉันต้องการนำไปใช้หรือไม่ ฉันต้องทำการวิจัยเพิ่มเติมเกี่ยวกับเรื่องนี้แล้วฉันจะรายงานกลับการตัดสินใจของฉัน

โดยพื้นฐานแล้วมีเพียงวิธีการเท่านั้นที่สามารถreturn- และเมื่อใช้คำหลักจากแลมบ์ดาแล้วคำหลักนั้นจะส่งคืนจากวิธีการที่ครอบคลุม

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

รายละเอียด

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