การสำรวจที่น่าสนใจในการออกแบบภาษาโปรแกรมได้เกิดขึ้น โดยเสนอการเปลี่ยนแปลงครั้งใหญ่จากตรรกะ boolean แบบดั้งเดิม ด้วยการแทนที่ค่า true/false ด้วย optional types แนวคิดนี้ท้าทายสมมติฐานพื้นฐานเกี่ยวกับวิธีที่ภาษาโปรแกรมจัดการกับตรรกะเงื่อนไขและการควบคุมการไหลของโปรแกรม
การแทนที่ Booleans ด้วย Options และ Results
แนวคิดหลักมุ่งเน้นไปที่การกำจัด boolean types ทั้งหมด แทนที่จะใช้ Option<()>
หรือ Result<(), ()>
types เพื่อแสดงสิ่งที่เราคิดแบบดั้งเดิมว่าเป็น true และ false ในระบบนี้ true
กลายเป็น Ok(unit)
และ false
กลายเป็น Err(unit)
แนวทางนี้เปลี่ยนคำสั่งเงื่อนไขจากการประเมิน boolean เป็นการดำเนินการที่อาจสำเร็จด้วยค่าหนึ่งหรือล้มเหลวด้วยสถานะข้อผิดพลาด
การตอบสนองของชุมชนมีความหลากหลายแต่เต็มไปด้วยความอยากรู้ทางปัญญา นักพัฒนาหลายคนเห็นความคล้ายคลึงกับแนวคิดการเขียนโปรแกรมเชิงฟังก์ชันที่มีอยู่แล้ว โดยเฉพาะ monads ใน Haskell ผู้แสดงความคิดเห็นคนหนึ่งสังเกตเห็นความคล้ายคลึงกับระบบ truthy/falsy ของ JavaScript แม้ว่าข้อเสนอนี้จะใช้แนวทางที่มีโครงสร้างมากกว่าผ่านความปลอดภัยของประเภทข้อมูล
ความเท่าเทียมของประเภทข้อมูลในระบบที่เสนอ:
bool
→Option<()>
true
→Ok(unit)
หรือSome(())
false
→Err(unit)
หรือNone
- ประเภท
test
→Result<(), ()>
(นามแฝง:??
)
การคิดใหม่เกี่ยวกับ Control Flow Operators
ภายใต้ระบบนี้ คำสั่ง if
แบบดั้งเดิมกลายเป็น binary operators ที่คืนค่า optional values คำสั่ง if
ที่ไม่มี else
clause จะคืนค่า Option<T>
ในขณะที่โครงสร้าง if-else
จะคืนค่า Option<T | U>
ตัวดำเนินการ and
และ or
จะทำงานกับ optional types ด้วย ทำให้เกิดระบบที่สม่ำเสมอมากขึ้นที่ตรรกะเงื่อนไขทั้งหมดทำงานบนโครงสร้างประเภทข้อมูลพื้นฐานเดียวกัน
สมาชิกชุมชนหลายคนชี้ให้เห็นการเชื่อมโยงกับภาษาและกระบวนทัศน์ที่มีอยู่แล้ว การดำเนินการที่มุ่งเป้าหมายของ Icon และ Lisp dialects ต่างๆ ได้ใช้แนวคิดที่คล้ายคลึงกันแล้ว โดยที่ nil
ทำหน้าที่เป็นค่า falsy เพียงค่าเดียว และทุกสิ่งอื่นถือว่าเป็น truthy
พฤติกรรมของตัวดำเนินการกับ Optional Types:
None and X
→None
Some(x) and Y
→Some(y)
None or X
→X
Some(x) or Y
→Some(x)
not Err
→Ok
not Ok
→Err
ผลกระทบในทางปฏิบัติและบริบททางประวัติศาสตร์
การอพิปรายเผยให้เห็นว่าแนวคิดนี้ไม่ใช่เรื่องใหม่ทั้งหมด ภาษาโปรแกรมเก่าหลายภาษา รวมถึง BASIC dialects ยุคแรกและ C ก่อน C99 ไม่มี boolean types เฉพาะ ภาษา Assembly โดยทั่วไปใช้การเปรียบเทียบจำนวนเต็มและ flag registers มากกว่าค่า boolean ที่ชัดเจน
ทุกสิ่งเก่าๆ กลายเป็นใหม่อีกครั้ง
ประโยชน์ในทางปฏิบัติรวมถึงการกำจัดความจำเป็นในการ wrap Some()
อย่างชัดเจนในหลายกรณี และการลดคำสั่ง early return ในฟังก์ชัน อย่างไรก็ตาม นักวิจารณ์กังวลเกี่ยวกับความซับซ้อนที่สิ่งนี้นำมา โดยเฉพาะเมื่อต้องจัดการกับรูปแบบข้อมูลภายนอกเช่น JSON ที่แยกความแตกต่างระหว่าง false
, null
และค่าที่ขาดหายไป
ภาษาโปรแกรมในอดีตที่ไม่มี Boolean เฉพาะ:
- ภาษา BASIC ส่วนใหญ่
- C ก่อน C99 (ใช้จำนวนเต็ม)
- ภาษา assembly ส่วนใหญ่
- FORTH (boolean ถูกกำหนดเป็น words)
- Emacs Lisp (มีเพียง
nil
เท่านั้นที่เป็น falsy) - Ruby (มีเพียง
false
และnil
เท่านั้นที่เป็น falsy)
ความสงสัยของชุมชนและความท้าทายทางเทคนิค
แม้ว่าความสง่างามทางทฤษฎีจะดึงดูดนักพัฒนาหลายคน แต่ข้อกังวลในทางปฏิบัติครอบงำการอพิปราย ระบบยังคงต้องการการตัดสินใจแบบไบนารีในระดับเครื่องจักร ทำให้บางคนโต้แย้งว่านี่เป็นเพียงการปกปิด booleans มากกว่าการกำจัดมัน การเขียนโปรแกรม GPU shader และเทคนิคการเขียนโปรแกรมแบบไม่มีสาขาแสดงให้เห็นแนวทางทางเลือกสำหรับตรรกะเงื่อนไขโดยไม่ใช้ boolean types แบบดั้งเดิมแล้ว
ข้อเสนอนี้เผชิญกับความท้าทายในสถานการณ์โลกแห่งความเป็นจริงที่ต้องการค่า boolean ที่ชัดเจน เช่น API responses หรือไฟล์การกำหนดค่า นักวิจารณ์แนะนำว่าผู้ใช้จะสร้าง wrapper types ที่ทำงานเหมือน booleans อย่างหลีกเลี่ยงไม่ได้ ซึ่งอาจทำให้ระบบซับซ้อนมากขึ้นแทนที่จะง่ายขึ้น
แม้จะมีข้อกังวลเหล่านี้ การสำรวจนี้ให้ข้อมูลเชิงลึกที่มีค่าเกี่ยวกับหลักการออกแบบภาษาและท้าทายนักพัฒนาให้พิจารณาแนวคิดการเขียนโปรแกรมพื้นฐานใหม่ ไม่ว่าจะปฏิบัติได้หรือไม่ การทดลองทางความคิดเช่นนี้ผลักดันขอบเขตของวิธีที่เราคิดเกี่ยวกับระบบประเภทข้อมูลและการควบคุมการไหลของโปรแกรมในภาษาโปรแกรม