ผู้ประกอบการมีความชัดเจนในการอ่านมากกว่าคำหลักหรือฟังก์ชั่น? [ปิด]


14

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

Haskell ค่อนข้างมีชื่อเสียงในเรื่องนี้เนื่องจากตัวดำเนินการแบบกำหนดเองนั้นง่ายต่อการสร้างและบ่อยครั้งที่ชนิดข้อมูลใหม่จะมาพร้อมกับตัวดำเนินการหลายตัวเพื่อใช้กับมัน ยกตัวอย่างเช่นห้องสมุด Parsec มาพร้อมกับตัวดำเนินการมากมายสำหรับการรวมตัวแยกวิเคราะห์เข้าด้วยกันด้วยอัญมณี>.และ.> ฉันจำไม่ได้ว่าพวกเขาหมายถึงอะไรในตอนนี้ แต่ฉันจำได้ว่าพวกเขาทำงานได้ง่ายมาก พวกเขาหมายถึงจริง ฟังก์ชั่นการโทรเช่นleftCompose(parser1, parser2)นี้ดีขึ้นหรือไม่ แน่นอนมากขึ้น verbose แต่ชัดเจนในบางวิธี

ตัวดำเนินการโอเวอร์โหลดในภาษา C เหมือนเป็นปัญหาที่คล้ายกัน แต่ conflated โดยปัญหาเพิ่มเติมของการบรรทุกเกินพิกัดความหมายของผู้ประกอบการที่คุ้นเคยเช่น+ความหมายใหม่ที่ผิดปกติ

ในภาษาใหม่ใด ๆ ดูเหมือนว่าจะเป็นปัญหาที่ค่อนข้างยาก ยกตัวอย่างเช่นใน F # การคัดเลือกนักแสดงใช้ตัวดำเนินการแคสติ้งประเภทที่ได้มาในเชิงคณิตศาสตร์แทนที่จะใช้ไวยากรณ์ของการส่งรูปแบบ C # หรือสไตล์ VB verbose C #: (int32) xVB: CType(x, int32)F #:x :> int32

ในทางทฤษฎีภาษาใหม่อาจมีโอเปอเรเตอร์สำหรับการใช้งานในตัวส่วนใหญ่ แทนที่จะdefหรือdecหรือvarสำหรับการประกาศตัวแปรทำไมไม่! nameหรือ@ nameหรือสิ่งที่คล้ายกัน แน่นอนว่ามันจะทำให้การประกาศสั้นลงตามด้วยการผูก: @x := 5แทนที่จะเป็นdeclare x = 5หรือlet x = 5 รหัสส่วนใหญ่จะต้องมีคำจำกัดความของตัวแปรจำนวนมากดังนั้นทำไมไม่

ผู้ประกอบการมีความชัดเจนและมีประโยชน์เมื่อใดและจะปิดบังเมื่อใด



1
ฉันหวังว่าหนึ่งในนักพัฒนา 1,000 คนที่เคยบ่นกับฉันเกี่ยวกับการขาดตัวดำเนินการมากเกินไปของ Java จะตอบคำถามนี้
smp7d

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

อย่างที่ฉันเห็นมันการขาดตัวดำเนินการโอเวอร์โหลดเป็นเรื่องที่น่ารังเกียจเพราะมันให้สิทธิพิเศษแก่ประเภทเนทิฟมากกว่าประเภทที่ผู้ใช้กำหนด (โปรดทราบว่า Java ทำสิ่งนี้ในลักษณะอื่นด้วย ฉันสับสนมากขึ้นเกี่ยวกับตัวดำเนินการแบบกำหนดเองของ Haskell ซึ่งดูเหมือนจะเป็นการเชื้อเชิญที่เปิดกว้างให้กับปัญหา ...
comingstorm

2
@comingstorm: จริง ๆ แล้วฉันคิดว่าวิธี Haskell ดีกว่า เมื่อคุณมีโอเปอเรเตอร์จำนวน จำกัด ที่คุณสามารถโอเวอร์โหลดได้หลายวิธีคุณมักจะถูกบังคับให้ใช้ตัวดำเนินการซ้ำในบริบทที่แตกต่างกัน (เช่น+สำหรับการต่อสตริงหรือ<<สตรีม) ในทางตรงกันข้าม Haskell ผู้ปฏิบัติงานเป็นเพียงแค่ฟังก์ชั่นที่มีชื่อที่กำหนดเอง (นั่นคือไม่ได้รับภาระมากเกินไป) หรือเป็นส่วนหนึ่งของคลาสประเภทซึ่งหมายความว่าในขณะที่มันเป็น polymorphic มันทำสิ่งตรรกะเดียวกันสำหรับทุกประเภทและ แม้มีลายเซ็นประเภทเดียวกัน ดังนั้น>>เป็น>>สำหรับทุกประเภทและไม่เคยไปจะมีการเปลี่ยนแปลงเล็กน้อย
Tikhon Jelvis

คำตอบ:


16

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

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

สุดท้าย Dijkstra เขียนเหตุผลที่น่าสนใจของสัญลักษณ์ทางคณิตศาสตร์ที่เขาใช้ซึ่งรวมถึงการสนทนาที่ดีของการแลกเปลี่ยนของ infix vs สัญลักษณ์คำนำหน้า


4
ฉันชอบที่จะให้ +1 ที่สองสำหรับลิงก์ไปยังกระดาษ Dijkstra
AProgrammer

ลิงค์ที่ดีคุณต้องเผยแพร่บัญชี PayPal! ;)
Adriano Repetti

8

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

ตัวอย่างเช่นdeclare x = 5อ่านเป็น"declare x equals 5"หรือlet x = 5สามารถอ่านได้"let x equal 5"ซึ่งเป็นที่เข้าใจได้ดีเมื่ออ่านออกมาดัง ๆ อย่างไรก็ตามการอ่าน@x := 5จะอ่านว่า"at x colon equals 5"(หรือ"at x is defined to be 5"ถ้าคุณเป็นนักคณิตศาสตร์) ซึ่งไม่สมเหตุสมผลเลย

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


5
ฉันไม่คิดว่า@x := 5เป็นเรื่องยากที่จะคิดออก - set x to be equal to 5ฉันยังอ่านออกเสียงให้ตัวเองเป็น
FrustratedWithFormsDesigner

3
@Rachel ในกรณีนั้น:=มีการใช้งานที่กว้างขึ้นในสัญกรณ์คณิตศาสตร์นอกภาษาโปรแกรม นอกจากนี้ข้อความเช่นx = x + 1กลายเป็นเรื่องเหลวไหลเล็กน้อย
ccoakley

3
กระแทกแดกดันฉันลืมว่าบางคนไม่ได้รับรู้:=ว่าเป็นงานที่มอบหมาย ใช้ภาษาสองสามภาษาจริง ๆ Smalltalk ฉันคิดว่าอาจเป็นที่รู้จักกันดีที่สุด ไม่ว่าการมอบหมายและความเท่าเทียมกันควรเป็นตัวดำเนินการที่แยกจากกันเป็นเวิร์มที่แตกต่างกันโดยสิ้นเชิงอย่างใดอย่างหนึ่งอาจครอบคลุมโดยคำถามอื่นแล้ว
CodexArcanum

1
@ccoakley ขอบคุณฉันไม่รู้ว่า:=ใช้ในวิชาคณิตศาสตร์ คำนิยามเดียวที่ฉันพบคือ"ถูกกำหนดให้เป็น"ดังนั้น@x := 5จะแปลเป็นภาษาอังกฤษเป็นภาษา"at x is defined to be 5"ซึ่งสำหรับฉันยังไม่สมเหตุสมผลเท่าที่ควร
Rachel

1
Pascal ใช้แน่นอน: = เป็นการกำหนดสำหรับการขาดลูกศรซ้ายใน ASCII
Vatine

4

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

แต่การขุดเพิ่มเติมเล็กน้อยมีสองด้าน

ไวยากรณ์ (ใส่สำหรับตัวดำเนินการซึ่งตรงข้ามกับคำนำหน้าสำหรับไวยากรณ์การเรียกใช้ฟังก์ชัน) และการตั้งชื่อ

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

เปรียบเทียบa * b + c * d + e * fกับ+(+(*(a, b), *(c, d)), *(e, f))หรือ+ + * a b * c d * e f(ทั้งคู่แยกวิเคราะห์ได้ในสภาพเดียวกับรุ่นมัด) ความจริงที่ว่าการ+แยกเงื่อนไขแทนที่จะนำหน้าหนึ่งในนั้นทำให้ฉันอ่านได้ง่ายขึ้นในสายตาของคุณ (แต่คุณต้องจำกฎก่อนหน้าซึ่งไม่จำเป็นสำหรับไวยากรณ์ของคำนำหน้า) หากคุณต้องการรวมสิ่งต่าง ๆ ในลักษณะนี้วิธีการผลประโยชน์ระยะยาวจะคุ้มค่ากับการเรียนรู้ และคุณรักษาความได้เปรียบนี้ไว้แม้ว่าคุณจะตั้งชื่อผู้ให้บริการด้วยตัวอักษรแทนที่จะใช้สัญลักษณ์

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

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


หากผู้ใช้สามารถเพิ่มโอเปอเรเตอร์ทำไมไม่ให้พวกเขาตั้งค่าลำดับความสำคัญและความสัมพันธ์ของโอเปอเรเตอร์ที่พวกเขาเพิ่มเข้าไป
Tikhon Jelvis

@TikhonJelvis มันเป็นเรื่องอนุรักษ์ส่วนใหญ่ แต่ก็มีบางประเด็นที่ต้องพิจารณาหากคุณต้องการใช้มันเพื่อสิ่งอื่นนอกเหนือจากตัวอย่าง ตัวอย่างเช่นคุณต้องการผูกลำดับความสำคัญและการเชื่อมโยงกับผู้ประกอบการไม่ใช่สมาชิกที่กำหนดของชุดที่โอเวอร์โหลด (คุณเลือกสมาชิกหลังจากการแยกวิเคราะห์เสร็จแล้วตัวเลือกไม่สามารถมีอิทธิพลต่อการแยกวิเคราะห์) ดังนั้นในการบูรณาการห้องสมุดโดยใช้ตัวดำเนินการเดียวกันพวกเขาจะต้องเห็นด้วยกับความสำคัญและความสัมพันธ์ ก่อนที่จะเพิ่มความเป็นไปได้ฉันจะพยายามหาสาเหตุว่าทำไมมีเพียงไม่กี่ภาษาที่ติดตามอัลกอล 68 (ไม่มี AFAIK) และอนุญาตให้นิยามมัน
AProgrammer

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

1

ตัวดำเนินการตามสัญลักษณ์นั้นมีประโยชน์เมื่อใช้งานได้อย่างเหมาะสม +และ-จะเห็นได้ชัดบวกและการลบตัวอย่างซึ่งเป็นเหตุผลที่สวยมากทุกภาษาที่เคยใช้พวกเขาเป็นผู้ประกอบการของพวกเขา เหมือนกับการเปรียบเทียบ ( <และ>ได้รับการสอนในระดับชั้นประถมศึกษา<=และ>=เป็นส่วนขยายที่ใช้งานง่ายของการเปรียบเทียบพื้นฐานเมื่อคุณเข้าใจว่าไม่มีปุ่มเปรียบเทียบที่ขีดเส้นใต้บนแป้นพิมพ์มาตรฐาน)

*และ/ไม่ชัดเจนในทันที แต่จะถูกใช้ในระดับสากลและตำแหน่งของพวกเขาบนแป้นตัวเลขที่อยู่ติดกับ+และ-ปุ่มจะช่วยจัดเตรียมบริบท C <<และ>>อยู่ในประเภทเดียวกัน: เมื่อคุณเข้าใจว่ากะซ้ายและกะขวาคืออะไรมันไม่ยากเกินไปที่จะเข้าใจความจำที่อยู่เบื้องหลังลูกศร

ถ้าอย่างนั้นคุณก็มาถึงสิ่งที่แปลกประหลาดอย่างแท้จริงสิ่งที่สามารถเปลี่ยนรหัส C เป็นซุปตัวดำเนินการที่อ่านไม่ได้ (การเลือกบน C ที่นี่เพราะมันเป็นตัวอย่างของตัวดำเนินการที่หนักมากซึ่งมีไวยากรณ์ที่ทุกคนคุ้นเคยกับการทำงานกับ C หรือด้วยภาษาที่สืบทอด) ตัวอย่างเช่นจากนั้น%ตัวดำเนินการ ทุกคนรู้ว่าคืออะไร: มันเป็นเครื่องหมายร้อยละ ... ใช่มั้ย ยกเว้นใน C ไม่มีส่วนเกี่ยวข้องกับการหารด้วย 100; มันเป็นตัวดำเนินการโมดูลัส นั่นทำให้รู้สึกเป็นศูนย์ความจำ แต่มี!

ที่แย่ยิ่งกว่านั้นคือตัวดำเนินการบูลีน &ในฐานะที่เป็นและทำให้รู้สึกยกเว้นว่ามีสอง&ผู้ประกอบการที่แตกต่างกันซึ่งทำสองสิ่งที่แตกต่างกันและทั้งสองมีความถูกต้อง syntactically ในกรณีใด ๆ ที่หนึ่งของพวกเขาถูกต้องแม้ว่าหนึ่งในพวกเขาเคยทำให้รู้สึกจริงในกรณีใดก็ตาม นั่นเป็นเพียงสูตรสำหรับความสับสน! หรือ , xorและไม่ได้ผู้ประกอบการจะยิ่งแย่ลงเพราะพวกเขาไม่ได้ใช้สัญลักษณ์ที่มีประโยชน์ mnemonically และไม่สอดคล้องอย่างใดอย่างหนึ่ง (ไม่มีตัวดำเนินการdouble- xorและตรรกะและ bitwise ไม่ใช้สัญลักษณ์สองแบบที่แตกต่างกันแทนสัญลักษณ์หนึ่งตัวและรุ่นสองเท่าขึ้นไป)

และเพื่อทำให้แย่ลงผู้ใช้งาน&และ*ผู้ใช้งานสามารถนำกลับมาใช้ใหม่ในสิ่งที่แตกต่างไปจากเดิมอย่างสิ้นเชิงซึ่งทำให้ภาษายากขึ้นสำหรับทั้งคนและคอมไพเลอร์ในการแยกวิเคราะห์ ( A * Bหมายความว่าอะไรมันขึ้นอยู่กับบริบททั้งหมด: เป็นAประเภทหรือตัวแปร)

เป็นที่ยอมรับว่าฉันไม่เคยพูดกับ Dennis Ritchie และถามเขาเกี่ยวกับการตัดสินใจในการออกแบบที่เขาทำในภาษา แต่มันรู้สึกว่าปรัชญาเบื้องหลังผู้ปฏิบัติงานเป็น "สัญลักษณ์เพื่อประโยชน์ของสัญลักษณ์"

เปรียบเทียบสิ่งนี้กับ Pascal ซึ่งมีโอเปอเรเตอร์เดียวกับ C แต่มีปรัชญาที่แตกต่างกันในการเป็นตัวแทน: ตัวดำเนินการควรใช้งานง่ายและอ่านง่าย ตัวดำเนินการทางคณิตศาสตร์เหมือนกัน ตัวดำเนินการโมดูลัสคือคำว่าmodเนื่องจากไม่มีสัญลักษณ์บนแป้นพิมพ์ที่เห็นได้ชัดว่าหมายถึง "โมดูลัส" ผู้ประกอบการตรรกะand, or, xorและnotและมีเพียงหนึ่งของแต่ละ; คอมไพเลอร์รู้ว่าคุณต้องใช้บูลีนหรือบิทในเวอร์ชันขึ้นอยู่กับว่าคุณใช้บูลีนหรือตัวเลขช่วยกำจัดข้อผิดพลาดทั้งชั้น นี้จะทำให้รหัสปาสกาลไกลเข้าใจง่ายกว่ารหัส C โดยเฉพาะอย่างยิ่งในตัวแก้ไขที่ทันสมัยด้วยการเน้นไวยากรณ์เพื่อให้ผู้ประกอบการและคำหลักสายตาที่แตกต่างจากตัวบ่งชี้


4
ปาสกาลไม่ได้แสดงถึงปรัชญาที่แตกต่างออกไปเลย หากคุณอ่านเอกสารของ Wirth เขาใช้สัญลักษณ์สำหรับสิ่งที่ชอบandและorตลอดเวลา อย่างไรก็ตามเมื่อเขาพัฒนาปาสคาลเขาก็ทำมันบนเมนเฟรมข้อมูลควบคุมซึ่งใช้อักขระ 6 บิต ที่บังคับให้ตัดสินใจที่จะใช้คำสำหรับหลายสิ่งหลายอย่างด้วยเหตุผลง่ายๆว่าชุดตัวอักษรก็ไม่ได้มีเกือบเป็นพื้นที่มากสำหรับสัญลักษณ์และเช่นบางอย่างเช่น ASCII ฉันใช้ทั้ง C และ Pascal และพบว่า C อ่านได้ง่ายกว่ามาก คุณอาจชอบ Pascal แต่นั่นเป็นเรื่องของรสนิยมไม่ใช่ความจริง
Jerry Coffin

หากต้องการเพิ่มคำพูดเกี่ยวกับ @JerryCoffin เกี่ยวกับ Wirth ภาษาที่ตามมา (Modula, Oberon) กำลังใช้สัญลักษณ์เพิ่มเติม
AProgrammer

@AProgrammer: และพวกเขาไม่เคยไปไหนเลย ;)
Mason Wheeler

ฉันคิดว่า|(และโดยการขยาย||) เพื่อหรือทำให้รู้สึก คุณจะเห็นตลอดเวลาสำหรับการสลับในบริบทอื่น ๆ เช่นไวยากรณ์และดูเหมือนว่าจะแบ่งสองตัวเลือก
Tikhon Jelvis

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

1

ฉันคิดว่าผู้ปฏิบัติงานสามารถอ่านได้มากขึ้นเมื่อฟังก์ชันของพวกเขาสะท้อนวัตถุประสงค์ทางคณิตศาสตร์ที่คุ้นเคย ตัวอย่างเช่นตัวดำเนินการมาตรฐานเช่น +, -, ฯลฯ สามารถอ่านได้มากกว่า Add หรือ Subtract เมื่อทำการบวกและลบ ต้องระบุพฤติกรรมของผู้ปฏิบัติงานอย่างชัดเจน ฉันสามารถทนต่อการโอเวอร์โหลดของความหมายของ + สำหรับการต่อข้อมูลรายการได้เช่นกัน เป็นการดีที่การดำเนินการจะไม่มีผลข้างเคียงคืนค่าแทนการกลายพันธุ์

ฉันเคยต่อสู้กับตัวดำเนินการทางลัดสำหรับฟังก์ชั่นแบบพับได้ เห็นได้ชัดว่าประสบการณ์มากขึ้นกับพวกเขาจะช่วยบรรเทานี้ แต่ฉันหาอ่านได้มากขึ้นกว่าfoldRight/:


4
อาจมีความถี่ในการใช้งานด้วยเช่นกัน ฉันไม่คิดว่าคุณfoldบ่อยพอที่ผู้ให้บริการจะประหยัดเวลาได้มาก นั่นอาจเป็นสาเหตุที่ LISPy (+ 1 2 3) ดูแปลก แต่ (เพิ่ม 1 2 3) ก็น้อยลง เรามักจะคิดว่าผู้ประกอบการเป็นไบนารีอย่างเคร่งครัด >>.ตัวดำเนินการลักษณะของ Parsec อาจโง่ แต่อย่างน้อยสิ่งที่คุณทำใน Parsec คือการรวม parsers ดังนั้นตัวดำเนินการสำหรับ Parsec จึงมีการใช้งานมาก
CodexArcanum

1

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

แน่นอนบรรทัดจะง่ายต่อการเขียนและอ่านกว่าC = A * x + b * cC = A.multiplyVector(x).addVector(b.multiplyScalar(c))

หรือแน่นอนว่ามันง่ายกว่าที่จะเขียนถ้าคุณมีผู้ให้บริการทั้งหมดที่อยู่ในหัวของคุณ และคุณสามารถอ่านได้หลังจากนั้นในขณะที่แก้ไขข้อผิดพลาดครั้งที่สองถึงครั้งสุดท้าย

ทีนี้สำหรับรหัสส่วนใหญ่ที่กำลังจะหมดลงนั่นก็ไม่เป็นไร "โครงการผ่านการทดสอบทั้งหมดและทำงาน" - สำหรับซอฟต์แวร์หลายชิ้นนั่นคือทั้งหมดที่เราต้องการ

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

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

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


0

ฉันคิดว่าตัวอย่างสุดขั้วคือ APL โปรแกรมต่อไปนี้คือ "เกมแห่งชีวิต":

life←{↑1 ⍵∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵}

และถ้าคุณสามารถคิดออกว่ามันหมายถึงอะไรโดยไม่ใช้เวลาสองสามวันกับคู่มืออ้างอิงขอให้คุณโชคดี!

ปัญหาคือคุณมีชุดของสัญลักษณ์ที่เกือบทุกคนเข้าใจโดยสังหรณ์ใจ: +,-,*,/,%,=,==,&

และส่วนที่เหลือซึ่งต้องการคำอธิบายบางอย่างก่อนจึงจะสามารถเข้าใจได้และโดยทั่วไปจะเฉพาะเจาะจงกับภาษานั้น ๆ ตัวอย่างเช่นไม่มีสัญลักษณ์ที่ชัดเจนเพื่อระบุสมาชิกของอาร์เรย์ที่คุณต้องการ [], () และแม้กระทั่ง "." มีการใช้งาน แต่ไม่มีคำหลักที่ชัดเจนที่คุณสามารถใช้งานได้ง่ายดังนั้นจึงมีกรณีที่ต้องใช้ตัวดำเนินการอย่างรอบคอบ แต่ไม่มากเกินไป

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