- Leslie Lamport เป็นผู้พัฒนาระยะแรกของ LaTeX และเป็นผู้บุกเบิกในวงการระบบกระจาย ได้รับรางวัลทัวริงในปี 2013
- ในคีย์โน้ตของเขาที่งาน SCaLE 22x เขาเน้นย้ำถึง ความสำคัญของนามธรรม โดยชี้ให้เห็นว่าโปรแกรมเมอร์ส่วนใหญ่มักหมกมุ่นกับการเขียนโค้ดและภาษา แต่ หัวใจสำคัญคือการคิดเชิงนามธรรมและการออกแบบก่อนลงมือเขียนโค้ด
สรุปการบรรยาย
- คุณอาจคาดหวังว่าผมจะพูดถึงความพร้อมกัน (Concurrency) แต่ผมไม่มีอะไรใหม่จะพูดในเรื่องนี้
- อย่างไรก็ตาม ข้อคิดเกี่ยวกับ “การเขียนโปรแกรมแบบ Concurrent” สามารถนำไปใช้ได้กับการเขียนโปรแกรมทั่วไปทั้งหมด
- การบรรยายนี้ว่าด้วยเรื่อง การเขียนโปรแกรม โดยรวม
อัลกอริทึม vs. โปรแกรม
- อัลกอริทึม: แนวคิดเชิงนามธรรมที่ไม่ขึ้นกับภาษา เป็น แนวคิดที่เป็นนามธรรมกว่าและอยู่ในระดับสูงกว่า โปรแกรม
- โปรแกรม: รูปธรรมของอัลกอริทึมที่ถูกนำไปเขียนในภาษาใดภาษาหนึ่ง ภาษาการเขียนโปรแกรมมีความซับซ้อนเกินไปสำหรับการใช้อธิบายอัลกอริทึม
- อัลกอริทึม ไม่ได้ถูกนำไปรัน และโดยทั่วไป สั้นและเรียบง่าย
- โดยเฉพาะโค้ดที่เกี่ยวกับ Concurrency นั้น ต้องนิยามอัลกอริทึมที่ถูกต้องให้ชัดเจนก่อน แล้วค่อยลงมือทำเป็นโค้ด
ดูนามธรรมผ่านตัวอย่างการหาค่าสูงสุดของอาร์เรย์
- แม้จะเป็นปัญหาง่าย ๆ ก็ต้อง นิยามให้ชัดก่อนว่าจะทำอะไร (What)
- ตัวอย่าง: “คืนค่ามากที่สุดของอาร์เรย์จำนวนเต็ม” → “คืนค่าจำนวนน้อยที่สุดที่มีค่ามากกว่าหรือเท่ากับทุกองค์ประกอบ”
- ต้องกำหนดล่วงหน้าด้วยว่าจะ จัดการอาร์เรย์ว่างอย่างไร (เช่น ใช้
-∞)
- นิยามที่ชัดเจนแบบนี้ช่วยให้ได้ อัลกอริทึม (How) ที่ง่ายและแข็งแรงกว่า
การรันโปรแกรมคือการไหลของสถานะ
- การทำงานของโปรแกรมไม่ใช่แค่ลำดับของคำสั่ง แต่คือ ความต่อเนื่องของสถานะ (state)
- การเปลี่ยนผ่านแต่ละสถานะหมายถึงการรันโค้ดบางส่วน
- มุมมองนี้ สำคัญต่อการพิสูจน์ความถูกต้องของอัลกอริทึม (เช่น การใช้ invariant)
เครื่องมือสำหรับระบบซับซ้อน: TLA+
- การแสดงนามธรรมอย่างแม่นยำจำเป็นต้องใช้ ภาษาที่เที่ยงตรง
- TLA+ คือเครื่องมือที่ออกแบบมาเพื่อจุดประสงค์นั้น
- Amazon Web Services ใช้ TLA+ เพื่อ ค้นพบข้อบกพร่องด้านการออกแบบร้ายแรงได้ล่วงหน้า
- Virtuoso ซึ่งเป็น OS ของยาน Rosetta ก็ถูกออกแบบบนพื้นฐานของ TLA+ เช่นกัน และได้โค้ดที่กระชับและเสถียร
บทบาทของนามธรรมแม้ในสเปกที่ไม่สมบูรณ์
- ตัวอย่าง: pretty printer อาจมีเกณฑ์การจัดแนวที่เป็นเรื่องของมุมมองส่วนบุคคล
- ถึงอย่างนั้น การกำหนด ชุดกฎเชิงนามธรรมไว้ล่วงหน้า ก็ยังสำคัญต่อการดีบักและการบำรุงรักษา
ความสัมพันธ์ระหว่างการเขียนกับการคิด
- การเขียนความคิดออกมาเป็นข้อความช่วยให้ความคิดชัดเจนขึ้น
- การทำ abstraction ไม่ใช่แค่คิดอยู่ในหัว แต่ ต้องเขียนออกมาด้วยจึงจะได้ผลจริง
- Lamport กล่าวว่าการฝึกฝนทางคณิตศาสตร์ของเขาช่วยพัฒนาความสามารถด้านนามธรรม
- นักคณิตศาสตร์สามารถสอนเรื่อง abstraction ให้โปรแกรมเมอร์ได้
มุมมองต่อไลบรารีและบั๊ก
- ในช่วงที่ 2 ของการบรรยาย “ทำไมโปรแกรมจึงต้องมีบั๊ก” เขาพูดถึงปัญหาความซับซ้อน
- ซอฟต์แวร์ยุคใหม่พึ่งพาไลบรารีจำนวนมาก แต่สิ่งเหล่านี้ ขาดคำอธิบายที่ถูกต้องและไม่ขึ้นกับภาษา
- ส่งผลให้ในขั้นตอนการรวมระบบ เกิดบั๊กที่ไม่คาดคิด
- ตัวอย่าง: ประสบการณ์ของเขาในการดีบัก JavaScript บนเว็บไซต์คอร์ส TLA+ ของตนเอง
- มุมมองแบบอิงสถานะ มีประโยชน์ต่อการทำความเข้าใจความซับซ้อนเหล่านี้
ประเด็นที่พูดถึงในช่วงถาม-ตอบ
- ผลกระทบที่ AI จะมีต่อนามธรรม
- ช่องว่างระหว่างโอเพนซอร์สกับแวดวงวิชาการ
- ความเป็นจริงที่นักพัฒนา มักละเลยนิยามเชิงรูปแบบ (formal definition)
- สิ่งที่ยังสำคัญที่สุดคือ “คิดก่อนเขียนโค้ด”
บทสรุป: แก่นแท้ของการเขียนโปรแกรมคือการคิด
- Lamport ยืนยันว่า ควรให้ความสำคัญกับการคิดเชิงนามธรรมและสเปกเชิงรูปแบบก่อนการเขียนโค้ดธรรมดา
- แม้ต้องลงแรงมากตั้งแต่ต้น แต่ท้ายที่สุดจะนำไปสู่ ซอฟต์แวร์ที่แข็งแรงกว่าและดูแลรักษาง่ายกว่า
- การเขียนโค้ดเป็นเพียงส่วนหนึ่งของการเขียนโปรแกรม ส่วนการเขียนโปรแกรมที่แท้จริง เริ่มต้นจากอัลกอริทึมที่แม่นยำและนามธรรม
- ในยุคปัจจุบันที่ความซับซ้อนของระบบและ Concurrency เพิ่มขึ้น นามธรรมคือทักษะที่จำเป็น และโปรแกรมเมอร์จำเป็นต้อง ฝึกการคิดและการทำ abstraction
5 ความคิดเห็น
ผมก็เห็นด้วยกับบทความนี้เช่นกัน
ผมมองว่าการนิยามปัญหาด้วยค่าสถานะที่ถูกทำให้อยู่ในระดับนามธรรมแล้วมีประโยชน์ต่อการค้นพบปัญหา และกำลังพยายามสร้างเครื่องมือจัดการสถานะที่ชัดเจนแบบมองเห็นได้และระบุได้อย่างชัดแจ้ง เช่น การทำภาพสถานะด้วยไดอะแกรม, Unreal Blueprint หรือ workflow
คงต้องมองที่ภาษาก่อนสินะ
เป็นบทความที่ทำให้นึกถึงวิชาเอกทฤษฎีการคำนวณเลยครับ! แนะนำให้คนที่ทำงานด้านโปรแกรมมิงลองศึกษาเพิ่มเติมดูครับ
สงสัยว่า TLA คืออะไร
คงต้องลองไปค้นหาดู
ผมก็เลยลองค้นหาดูเหมือนกันครับ
TLA+ - ภาษาระดับสูงสำหรับการทำแบบจำลองโปรแกรมและระบบพร้อมกัน/ระบบกระจาย
ความเห็นจาก Hacker News
เหล่า 'coder' ในวงการ demoscene เรียกตัวเองแบบนั้นด้วยความภาคภูมิใจ และพวกเขาก็มักจะเป็นทั้ง 'programmer' และ 'software engineer' ที่ยอดเยี่ยมด้วย ไม่ว่าจะใช้คำว่า coder, programmer หรือ software engineer สิ่งสำคัญคือทำให้คอมพิวเตอร์ทำงานได้ตามต้องการ
คีย์โน้ตของปีถัดไปน่าจะเป็น 'vibing ไม่ใช่การเขียนโค้ด และไม่ใช่การเขียนโปรแกรม...; เป็นพีระมิดของขยะที่พอทำงานได้บ้างเป็นครั้งคราว' โชคดีที่ Dijkstra ไม่ได้มาเห็นสิ่งนี้ เขายังเคยหัวเสียอยู่ในห้องนั่งเล่นบ้านพ่อแม่ตั้งแต่ยุค 80 แล้ว นึกไม่ออกเลยว่าเขาจะมีปฏิกิริยาอย่างไรถ้าได้เห็น 'vibe coding'
คีย์โน้ต SCaLE 22x ของ Leslie Lamport: คิดก่อน ทำ abstraction ก่อน แล้วค่อยเขียนโค้ด Lamport เรียกร้องให้เกิดการเปลี่ยนแปลงพื้นฐานในแนวทางการเขียนโปรแกรม โดยเน้นการคิดและการทำ abstraction ก่อนลงมือเขียนโค้ด ซึ่งใช้ได้กับโค้ดที่ไม่ใช่เรื่องเล็กน้อยทั้งหมด
การเขียนโปรแกรมควรเป็นกระบวนการที่มีเจตนา เริ่มจากการออกแบบอย่างรอบคอบ (abstraction) แล้วจึงค่อยลงมือทำจริง (coding) โดยให้ความสำคัญกับสเปกที่ชัดเจนและการทำความเข้าใจพฤติกรรมของโปรแกรมผ่านลำดับของ state และ invariant การคิดก่อนย่อมดีกว่าเสมอ
อาจารย์คณิตศาสตร์เรียกทุกการกระทำที่แปลงแนวคิดให้อยู่ในรูปที่แม่นยำขึ้นและเครื่องอ่านได้ว่าเป็น coding ไม่ได้มีแค่การเขียนสิ่งที่ต้องการให้คอมพิวเตอร์ทำในภาษาโปรแกรม แต่รวมถึงการเข้ารหัสข้อมูลด้วย คำว่า "encode" ทำให้เรื่องนี้ชัดขึ้น เขาเคยมอบหมายงานให้กำหนดวิธี coding ที่แปลง binary tree ให้เป็นจำนวนธรรมชาติ คำว่า coding คลุมเครือเกินไป จึงไม่ค่อยได้ใช้มากนัก
Lamport ยืนยันว่าควรแยก "what" ออกจาก "how" แต่ก็ชวนสงสัยว่าในปัญหาส่วนใหญ่ "what" และ "how" ของโปรแกรมไม่ได้ผสานกันอยู่ระดับหนึ่งหรอกหรือ ตัวอย่างเช่น ประเด็นด้านประสิทธิภาพเป็นส่วนหนึ่งของ "what" หรือเป็นส่วนหนึ่งของ "how"?
สรุปได้น่าสนใจ: อัลกอริทึมไม่ใช่โปรแกรม ไม่ควรเขียนด้วยภาษาโปรแกรม และควรเรียบง่าย ในทางกลับกัน โปรแกรมต้องรันได้รวดเร็วบนชุดข้อมูลที่อาจมีขนาดใหญ่ จึงจำเป็นต้องซับซ้อน โดยเฉพาะเมื่อพูดถึงโปรแกรมแบบ concurrent ที่รันบนหลาย CPU เพราะลำดับการทำงานอาจแตกต่างกัน
นิยามโปรแกรมว่าเป็นโค้ดที่ต้องคิดก่อนเขียน และเป็นโค้ดสำหรับให้คนที่ไม่อยากอ่านโค้ดมาใช้งาน การบรรยายนี้ดำเนินมาเป็นเวลานานแล้ว ตัวอย่างการทำให้การหาค่าที่เล็กที่สุดเรียบง่ายลงนั้นตรงกับ "Define Errors Out of Existence" ในหนังสือของ John Ousterhout แบบเป๊ะ ๆ
รู้สึกขำกับความย้อนแย้งที่คอมเมนต์ส่วนใหญ่เต็มไปด้วยคนที่ไม่เข้าใจสารที่ต้องการสื่อ แก่นของ Leslie Lamport คือการพัฒนาความสามารถในการคิดเชิงนามธรรมจะนำไปสู่โปรแกรมที่ดีขึ้น abstraction ในความหมายทางคณิตศาสตร์และตรรกะช่วยให้ตัดรายละเอียดที่ไม่เกี่ยวข้องทั้งหมดออกไปได้ การพัฒนาซอฟต์แวร์ที่มี AI ช่วยชี้นำก็เช่นกัน
อย่างที่คาดได้กับทุกเรื่องที่เกี่ยวข้องกับความเคร่งครัด ผู้คนจำนวนมากอ่านแค่พาดหัวแล้วตอบสนองในแง่ลบ คำว่า hacker บน Hacker News อาจหมายถึง programmer ที่มีทักษะและแก้ปัญหาได้ แต่ทุกวันนี้มันก็อาจหมายถึง "You're a Hack" คือคนไร้ความสามารถที่สร้างผลงานคุณภาพต่ำได้เช่นกัน
การบรรยายและการถกเถียงนี้จุกจิกเกินไป
ตอนนี้มีบทความดี ๆ ใน ACM ที่พูดถึงว่าถึงแม้จะไม่เห็นด้วยว่า abstraction คืออะไร แต่ก็ยังมีประโยชน์มาก ส่วนใหญ่เห็นด้วยว่าประเด็นสำคัญอยู่ตรงไหน เพียงแต่ไม่เห็นด้วยว่ามันคืออะไรอย่างแน่ชัด และทำไมมันถึงสำคัญ บทความนี้ให้แรงบันดาลใจได้มาก ซึ่งแค่นั้นก็มีคุณค่าในตัวเองแล้ว
Hacking ไม่ใช่การเขียนโค้ด ไม่ใช่การเขียนโปรแกรม ไม่ใช่การพัฒนาซอฟต์แวร์ และไม่ใช่วิศวกรรมซอฟต์แวร์ แต่ท้ายที่สุดแล้ว หลายคนก็ใช้คำเหล่านี้แทบจะสลับกันได้ และโดยส่วนตัวแล้ว การเน้นย้ำความต่างของนิยามที่แต่ละคนใช้ก็แทบไม่ใช่การใช้เวลาที่ก่อประโยชน์นัก