ตัวแปลภาษา Lisp ที่เขียนด้วยภาษา C เพียง 99 บรรทัดได้จุดประกายการถกเถียงอย่างร้อนแรงในชุมชนโปรแกรมเมอร์เกี่ยวกับการบีบอัดโค้ดอย่างสุดขั้วที่อาจมีต้นทุนสูงเกินไป โปรเจกต์ที่เรียกว่า tinyLisp พยายามบรรจุตัวแปลภาษา Lisp ที่ใช้งานได้จริงพร้อมฟังก์ชันพื้นฐาน 21 ตัว ระบบเก็บขยะ และ REPL ลงในโค้ด C น้อยกว่า 100 บรรทัด
คุณสมบัติของ TinyLisp :
- โค้ด C 99 บรรทัด (เฉลี่ย 55 บรรทัดซอร์สโค้ด)
- มี Lisp primitives ในตัว 21 ตัว
- ระบบ garbage collection แบบง่าย
- REPL (Read-Eval-Print Loop)
- รองรับ static scoping
- การคำนวณจุดทศนิยมแบบความแม่นยำสูง
- ความกว้างสูงสุด 120 คอลัมน์สำหรับการแก้ไข
![]() |
---|
ตัวอย่างการใช้งานในตัวแปลภาษาคล้าย Lisp แสดงการใช้งาน lambda functions และ currying ซึ่งสะท้อนฟังก์ชันการทำงานของ tinyLisp |
ข้อกังวลเรื่องคุณภาพโค้ดครองความสนใจหลัก
การใช้งานนี้ได้รับการวิพากษ์วิจารณ์อย่างรุนแรงจากนักพัฒนาที่โต้แย้งว่าการไล่ตามความกระชับส่งผลให้เกิดปัญหาในการเขียนโค้ด นักวิจารณ์ชี้ไปที่ปัญหาทางเทคนิคหลายประการ รวมถึงการใช้ประเภทข้อมูล double ในทางที่ผิด ปัญหาการพึ่งพา endian และการละเมิด strict aliasing ที่อาจทำให้โค้ดไม่สามารถทำงานบนคอมไพเลอร์สมัยใหม่ได้ นักพัฒนาบางคนยังค้นพบข้อผิดพลาดทางไวยากรณ์ในเวอร์ชันปัจจุบัน โดยมีวงเล็บปิดเพิ่มเติมในบรรทัดที่ 81 ที่ทำให้คอมไพล์ไม่ได้
ผู้เขียนใช้เทคนิคที่เรียกว่า NaN-boxing ซึ่งข้อมูลประเภทจะถูกเก็บไว้ในไบต์แรกของตัวเลขทศนิยมแบบความแม่นยำคู่ แม้ว่าวิธีการนี้จะถูกใช้ในระบบที่ใช้งานจริงเช่น JavaScript engines และ Ruby แต่การใช้งานใน tinyLisp ถูกวิพากษ์วิจารณ์ว่าให้ความสำคัญกับขนาดมากกว่าความชัดเจน
ปัญหาทางเทคนิคที่ระบุได้:
- ข้อผิดพลาดทางไวยากรณ์ในบรรทัดที่ 81 (วงเล็บปิดเกิน)
- การใช้ double data type ในทางที่ผิดสำหรับการติดแท็กประเภทข้อมูล
- ปัญหาการพึ่งพา Endian
- การละเมิด strict aliasing
- ขาดการปรับปรุงประสิทธิภาพ tail call optimization ( TCO )
- ปัญหาความเข้ากันได้กับคอมไพเลอร์สมัยใหม่
การแลกเปลี่ยนระหว่างความอ่านง่ายกับความกระชับ
สมาชิกชุมชนจำนวนมากได้แสดงความชอบในโค้ดที่ยาวกว่าและอ่านง่ายกว่าแทนที่จะเป็นแบบบีบอัด การใช้งานทางเลือกได้รับการเน้นย้ำ รวมถึงเวอร์ชัน 700 บรรทัดที่เรียกว่า fe ที่ให้ความสำคัญกับความชัดเจนและโครงสร้างเอกสารที่เหมาะสม ฉันทามติในหมู่นักวิจารณ์ดูเหมือนจะเป็นว่าการเพิ่มจำนวนบรรทัดเป็นสองหรือสามเท่าจะคุ้มค่าหากส่งผลให้ได้โค้ดที่บำรุงรักษาและเข้าใจได้
ผมชอบโค้ด 200 บรรทัดที่อ่านง่ายและดีจริงๆ มากกว่า
การใช้งานทางเลือก:
- fe: การใช้งาน C ที่ชัดเจน 700 บรรทัดพร้อมเอกสารประกอบที่ดีกว่า
- เวอร์ชัน Python: ประมาณ 100 บรรทัดพร้อมการใช้งาน lispy.html ของ Norvig
- tinylisp-extras.c: เวอร์ชันขยายที่รองรับ TCO
ความสามารถทางเทคนิคและข้อจำกัด
แม้จะมีการวิพากษ์วิจารณ์ แต่ tinyLisp ก็มีฟังก์ชันการทำงานที่สำคัญเมื่อเทียบกับขนาด ตัวแปลภาษานี้รองรับ static scoping การคำนวณทศนิยมแบบความแม่นยำคู่ และรวมถึงการดำเนินการ Lisp ที่จำเป็น อย่างไรก็ตาม การใช้งานดูเหมือนจะขาดการเพิ่มประสิทธิภาพ tail call (TCO) ซึ่งจำกัดความสามารถในการรันฟังก์ชันแบบเรียกซ้ำเช่น Y-combinator โดยไม่เสี่ยงต่อ stack overflow
โปรเจกต์รวมถึงเวอร์ชันที่เพิ่มประสิทธิภาพเพื่อความเร็วที่ดีขึ้นและการใช้หน่วยความจำที่ลดลง และผู้เขียนได้ให้ตัวอย่างการขยายสำหรับเพิ่มฟีเจอร์ Lisp เพิ่มเติม
สรุป
โปรเจกต์ tinyLisp ทำหน้าที่เป็นกรณีศึกษาที่น่าสนใจในการถกเถียงอย่างต่อเนื่องระหว่างความสำเร็จของ code golf กับการพัฒนาซอฟต์แวร์เชิงปฏิบัติ แม้ว่าความสำเร็จทางเทคนิคของการใช้งานตัวแปลภาษา Lisp ที่ใช้งานได้ใน 99 บรรทัดจะน่าประทับใจ แต่การตอบสนองของชุมชนแสดงให้เห็นว่าการบีบอัดอย่างสุดขั้วเช่นนี้อาจไม่คุ้มค่ากับความท้าทายด้านการบำรุงรักษาและความน่าเชื่อถือที่เกิดขึ้น การถกเถียงนี้เน้นย้ำถึงความสำคัญของการสร้างสมดุลระหว่างนวัตกรรมกับคุณภาพโค้ดในโปรเจกต์การเขียนโปรแกรมในโลกแห่งความเป็นจริง
อ้างอิง: Lisp in 99 lines of C and how to write one yourself