ทำไมการไม่เข้าใจโค้ดเบสทั้งหมดก็ไม่เป็นไร
(seangoedecke.com)- ระบบขนาดใหญ่ที่มีโค้ดนับสิบล้านบรรทัดเป็นสิ่งที่ไม่มีใครสามารถเก็บภาพรวมทั้งหมดไว้ในหัวได้ ดังนั้นวิศวกรจึงต้องสามารถทำงานได้อย่างมีประสิทธิภาพแม้มีเพียง ความเข้าใจที่ถูกต้องบางส่วน
- งานเขียน Programming as Theory Building ของ Peter Naur มองว่าเมื่อความเข้าใจของทีมเดิมหายไป การทิ้งโปรแกรมแล้วสร้างใหม่อาจดีกว่า แต่ระบบขนาดใหญ่ที่มีผู้ใช้และข้อยกเว้นจำนวนมากพัวพันกันอยู่นั้นสร้างขึ้นใหม่ทั้งหมดตั้งแต่ต้นได้ยาก
- แม้แต่โค้ดเบสที่ผู้รับผิดชอบออกไปหมดแล้วก็ยังฟื้นขึ้นมาได้ หากเริ่มจากทำความเข้าใจหนึ่ง flow ให้ครบตั้งแต่ต้นจนจบ แล้วค่อย ๆ ขยายขอบเขตการเปลี่ยนแปลงอย่างระมัดระวัง และในองค์กรขนาดใหญ่ การ สร้างความเข้าใจขึ้นใหม่ แบบนี้เกิดขึ้นซ้ำแล้วซ้ำอีก
- LLM อาจขัดขวางการสร้าง mental model ที่ละเอียด แต่ก็ช่วยให้สร้างและใช้ความเข้าใจบางส่วนได้รวดเร็วขึ้น อีกทั้งการทำงานร่วมกัน ข้อกำหนดทางกฎหมาย การอัปเดตด้านความปลอดภัย และการนำ dependency เข้ามา ล้วนต้องการ การแลกเปลี่ยนกับคุณค่าอื่นนอกเหนือจากความเข้าใจโค้ด
- mental model ที่แม่นยำช่วยให้การพัฒนาราบรื่นและมั่นคงขึ้น แต่ไม่ใช่มาตรฐานสัมบูรณ์ และในงานจริงก็อาจจำเป็นต้อง ยอมละทิ้งความเข้าใจอย่างสมบูรณ์ เพื่อความเร็ว การปฏิบัติตามกฎหมาย และความต้องการขององค์กร
ความเข้าใจอย่างสมบูรณ์กับความเข้าใจบางส่วน
- ในโค้ดเบสขนาดเล็กที่มีการเปลี่ยนตัวสมาชิกไม่บ่อย มักเชื่อกันได้ง่ายว่าต้องเข้าใจทั้งหมดจึงจะทำงานได้ดี
- โปรเจ็กต์อย่าง Redis หรือ The Witness) จัดอยู่ในกลุ่มนี้
- ในโค้ดเบสอย่าง backend ของ Google Search หรือ GitHub ที่มีขนาดใหญ่และมีการเปลี่ยนคนบ่อย ไม่มีใครเข้าใจทั้งหมดได้ จึงทำงานกันด้วยการพยายามทำความเข้าใจ พื้นที่เฉพาะจุด ที่ตนรับผิดชอบให้มากที่สุด
- สองสภาพแวดล้อมนี้มีวิธีพัฒนา แนวปฏิบัติ และวัฒนธรรมที่ต่างกันมาก แต่ในการถกเถียงด้าน software engineering บนออนไลน์ วัฒนธรรมแบบแรกที่ให้ความสำคัญกับความเข้าใจอย่างสมบูรณ์กลับถูกนำเสนอมากเกินไป
- วิศวกรโอเพนซอร์ซมีแรงจูงใจสูงที่จะถ่ายทอดงานของตนออกมาเป็นลายลักษณ์อักษร และงานวิศวกรรมล้วน ๆ ก็มักโดดเด่นได้ง่ายกว่าระบบ proprietary ขนาดใหญ่
- ระบบ proprietary เปิดเผยได้ยากด้วยเหตุผลทางกฎหมาย และถึงเปิดเผยได้ การอธิบายโค้ดเบสขนาดใหญ่ก็ยังต้องใช้บริบทเฉพาะจำนวนมากเกินไป
- ในสภาพแวดล้อมซอฟต์แวร์จำนวนมาก ความเข้าใจบางส่วน ไม่ใช่สภาวะที่ผิด และสำหรับระบบขนาดใหญ่ นี่คือสิ่งที่ดีที่สุดที่เข้าถึงได้ในความเป็นจริง
- ความต่างนี้นำไปสู่ปัญหาการปะทะกันระหว่างวัฒนธรรมของความเข้าใจอย่างสมบูรณ์กับวัฒนธรรมของความเข้าใจบางส่วนที่แยกไว้ใน Pure and impure software engineering
ข้อเสนอของ Programming as Theory Building
- บทความ Programming as Theory Building ของ Peter Naur มองว่าผลลัพธ์หลักที่โปรแกรมเมอร์สร้างขึ้นไม่ใช่โค้ด แต่คือ ทฤษฎีเกี่ยวกับโปรแกรม
- ทฤษฎีนี้ประกอบด้วยความเข้าใจเชิงสัญชาตญาณว่าอะไรเกิดขึ้นและทำไมจึงเกิดขึ้น
- โค้ดและเอกสารถ่ายทอดความเข้าใจนั้นได้เพียงบางส่วนเท่านั้น
- แม้โค้ดจะสูญหายไป ทีมที่ยังมีทฤษฎีนี้อยู่ก็สามารถเขียนโปรแกรมขึ้นใหม่ได้ แต่ถ้าทีมถูกเปลี่ยนออกทั้งหมดจนความเข้าใจหายไป ก็จะเข้าใจโค้ดเดิมได้ยาก
- ตามมุมมองของ Naur เราไม่สามารถสร้างทฤษฎีเดิมขึ้นใหม่ได้จากเอกสารหรือโค้ดเพียงอย่างเดียว ดังนั้นควรทิ้งโปรแกรมเดิมและให้ทีมใหม่แก้ปัญหาใหม่ตั้งแต่ต้น
- The Concept of Mind ของ Gilbert Ryle ซึ่ง Naur อ้างถึง มองขอบเขตของการสร้างทฤษฎีไว้กว้างกว่านั้น
- ในการลงมือทำอะไรบางอย่างจริง ๆ ทฤษฎีหรือ know-how อาจค่อย ๆ ก่อตัวขึ้นตามธรรมชาติ
- เพราะฉะนั้น กระบวนการทำความเข้าใจโค้ดเบสเดิมผ่านการสำรวจตัวโค้ดเองก็สอดคล้องกับแนวทางนี้เช่นกัน
ทำไมระบบขนาดใหญ่จึงเขียนใหม่ทั้งหมดตั้งแต่ต้นไม่ได้
- ระบบที่ใหญ่พอและมีผู้ใช้งานจะสะสม กรณียกเว้นและพฤติกรรมประหลาด หลายพันแบบที่นำกลับไปทำซ้ำได้ยาก
- แม้แต่ทีมที่รู้จักระบบดี ก็ยังไม่สามารถคำนึงถึงรายละเอียดทั้งหมดพร้อมกันได้ จึงเขียนใหม่ทั้งระบบในคราวเดียวได้ยาก
- การเขียนใหม่ที่ประสบความสำเร็จมักทำโดยแบ่งโค้ดเบสเดิมออกเป็นส่วนเล็ก ๆ ที่แยกจากกันได้ แล้ว ค่อย ๆ เปลี่ยนทีละส่วน
- สุดท้ายแล้ว การเขียนใหม่ก็คือการทำชุดของการเปลี่ยนแปลงบนระบบเดิม
- ถ้ายังเปลี่ยนระบบเดิมไม่ได้ การแทนที่ทั้งหมดด้วยระบบใหม่ก็ยิ่งยากกว่าเดิม
วิธีฟื้นโค้ดเบสที่ถูกทิ้งร้าง
- ในบริษัทเทคโนโลยีที่มีโค้ดหลายร้อยล้านบรรทัดและมีวิศวกรหลายพันคน ไม่ใช่เรื่องแปลกที่จะเกิดสถานการณ์ที่ไม่มีใครเหลืออยู่ที่รู้จักโค้ดเบสหนึ่ง ๆ อย่างแท้จริง
- แค่คนรับผิดชอบไม่กี่คนลาออกในจังหวะไม่ดี หรือโค้ดเบสถูกปล่อยทิ้งไม่บำรุงรักษาเป็นเวลา 1 ปี ก็อาจเกิดสภาพนี้ได้แล้ว
- Naur มองว่าแทบจะไม่มีใครมอบหมายให้โปรแกรมเมอร์ใหม่กู้คืนโปรแกรมที่ตายสนิทโดยไม่มีใครเหลือที่รู้ทฤษฎีเดิมเลยแม้แต่น้อย แต่ในองค์กรขนาดใหญ่ สิ่งนี้เกิดขึ้นจริง
- แม้เป็นโค้ดเบสที่ถูกทิ้งร้าง ก็ยังสามารถใช้เวลาเพื่อสร้างความเข้าใจชุดใหม่ขึ้นมา และทำให้กลับสู่สภาพที่ทำงานได้อย่างมีประสิทธิภาพ
- เริ่มจากทำความเข้าใจ processing flow หนึ่งเส้น ตั้งแต่ต้นจนจบ
- จากนั้นค่อย ๆ เปลี่ยนอย่างระมัดระวัง และขยายขอบเขตความเข้าใจจาก flow นั้นออกไปยังพื้นที่รอบข้าง
ทุกคนล้วนทำงานด้วยทฤษฎีที่ไม่สมบูรณ์
- ซอฟต์แวร์สมัยใหม่ขนาดใหญ่มีขนาดเกินกว่าที่ทั้งคนคนเดียวหรือแม้แต่ทั้งทีมจะเก็บพฤติกรรมทั้งหมดไว้ในหัวได้
- ในโค้ดเบสที่ใหญ่พอ ทุกคนย่อมต้องทำงานโดยมี ทฤษฎีที่คลาดเคลื่อนอยู่บ้าง เกี่ยวกับโปรแกรม
- วิศวกรที่มีประสิทธิภาพจะไม่รอจนกว่าจะมีคนที่เข้าใจทุกอย่างมาตอบ แต่จะตัดสินใจอย่างมีเหตุผลที่สุดจากข้อมูลที่มีอยู่ในตอนนั้น แล้วรับมือกับผลลัพธ์ที่ตามมา
- การทำงานแบบนี้ต้องอาศัย ความสามารถในการเลือกจุดยืน และ ความมั่นใจ แม้อยู่ในสถานการณ์ที่ไม่แน่นอน
- ความจริงที่ว่าไม่มีใครรู้พฤติกรรมทั้งหมดของผลิตภัณฑ์ขนาดใหญ่ได้อย่างสมบูรณ์ ก็เหมือนกับสิ่งที่กล่าวถึงใน Nobody knows how software products work
ขนาดของโค้ดในยุคของ Naur กับยุคปัจจุบัน
- ตอนที่ Naur เขียนบทความในปี 1985 ขนาดเฉลี่ยของโปรแกรมอาจเล็กกว่าวันนี้อยู่หลายลำดับขั้น
- ตัวอย่างโปรแกรมขนาดใหญ่ตัวแรกที่ Naur ยกมาคือโปรแกรมมอนิเตอร์งานอุตสาหกรรมขนาด 200,000 บรรทัด และตัวอย่างที่สองคือคอมไพเลอร์
- GCC เวอร์ชันแรกในปี 1987 มีขนาดประมาณ 100,000 บรรทัด แต่ในปี 2015 เพิ่มเป็น มากกว่า 14 ล้านบรรทัด
- หากสามารถนำการทดสอบเดิมกลับมาใช้ได้ โปรแกรมขนาด 100,000–200,000 บรรทัดอาจเขียนใหม่ได้ค่อนข้างง่าย แต่เป็นการยากที่จะใช้ข้อสรุปเดียวกันกับระบบขนาด 1–2 ล้านบรรทัดขึ้นไป
LLM กับความเป็นสองด้านของการสร้างทฤษฎี
- LLM มักถูกมองว่าเป็นเครื่องมือที่ไม่ดี เพราะไปรบกวน กระบวนการสร้างทฤษฎี ตามปกติ
- แต่เช่นเดียวกับเครื่องมือซอฟต์แวร์อื่น ๆ LLM ก็มีทั้งสองด้าน
- มันอาจทำให้การสร้าง mental model ของซอฟต์แวร์อย่างละเอียดทำได้ยากขึ้น
- แต่มันช่วยให้สร้างทฤษฎีแบบบางส่วนได้รวดเร็ว
- และช่วยให้ทำงานได้มีประสิทธิภาพขึ้นแม้อาศัยความเข้าใจที่ไม่สมบูรณ์
- ความสัมพันธ์ระหว่าง LLM กับความเข้าใจโค้ดไม่อาจสรุปแบบง่าย ๆ ว่ามีแต่ข้อดีหรือข้อเสีย แต่ยังเป็น trade-off ที่ซับซ้อนและต้องใช้วิจารณญาณ
ทางเลือกที่จำเป็นแม้ทำให้เข้าใจโค้ดยากขึ้น
- ปัจจัยที่ทำให้การรักษาทฤษฎีที่แม่นยำของโค้ดเบสทำได้ยาก ไม่ได้มีแค่ LLM
- การยอมให้ผู้อื่นเขียนโค้ดลงในโค้ดเบสเดียวกัน
- การพัฒนาฟีเจอร์ที่ กฎหมายกำหนดให้ต้องมี เช่น accessibility หรือการคุ้มครองข้อมูล
- การยอมให้เพื่อนร่วมงานลาออกหรือย้ายทีมได้
- การอัปเกรดเวอร์ชันซอฟต์แวร์เพื่อออก security patch
- การนำไลบรารีหรือ dependency อื่นเข้ามาใช้
- เราไม่อาจตัดสินว่าเครื่องมือหรือแนวปฏิบัติใดไม่ดี เพียงเพราะมันขัดขวางการสร้างทฤษฎี
- ความเข้าใจโค้ดเบสก็เหมือนกับ readability, maintainability และ correctness คือเป็นหนึ่งในคุณค่าทางวิศวกรรมหลายด้าน
- ในบางสถานการณ์ เราอาจยอมเสียคุณค่าอื่นเพื่อให้ความสำคัญกับความเข้าใจที่แม่นยำ
- ในทางกลับกัน เราก็อาจยอมลดระดับความเข้าใจโค้ดเพื่อแลกกับความเร็ว การปฏิบัติตามกฎหมาย หรือเหตุผลทางการเมืองภายในองค์กร
- ข้อโต้แย้งที่ว่าความเข้าใจโค้ดคือแกนกลางสำหรับทำให้คุณค่าอื่นทั้งหมดเกิดขึ้นได้ ก็สามารถใช้กับ readability, maintainability และ correctness ได้เหมือนกัน และในโลกการทำงานจริง คุณค่าแกนกลางเหล่านี้ก็ยังต้องถูกนำมาแลกเปลี่ยนอยู่เสมอ
ความชอบส่วนตัวกับความรับผิดชอบในการทำงาน
- โดยเฉพาะ วิศวกรสายบริสุทธิ์ มักชอบทำงานโดยรักษา mental model ที่แม่นยำไว้
- การพัฒนาสนุกกว่าและเครียดน้อยกว่า
- ให้ความรู้สึกว่าใกล้กับสิ่งที่ตนมองว่าเป็นงานวิศวกรรมที่แท้จริงมากกว่า
- เหตุผลที่วิศวกรจำนวนมากสร้างโปรเจ็กต์โอเพนซอร์ซขนาดเล็กด้วยตัวเองในเวลาว่าง ก็เพราะพวกเขาสามารถทำงานไปพร้อมกับรักษา ทฤษฎีแบบ Naur ที่แม่นยำเกี่ยวกับโค้ดเบสได้
- ในการทำงานจริง เราต้องเดินตามชุดคุณค่าที่องค์กรเป็นผู้จ่ายเงินและต้องการ มากกว่าจะยึดคุณค่าทางวิศวกรรมส่วนบุคคล
- แม้จะให้ความสำคัญกับ performance ก็ยังอาจต้องเขียนโค้ดที่ช้าลงเพื่อให้ทันกำหนดหรือรองรับข้อกำหนดที่ยุ่งยาก
- ความเข้าใจโค้ดเบสอย่างสมบูรณ์เองก็ไม่ใช่มาตรฐานสัมบูรณ์ที่ต้องรักษาไว้เสมอไป แต่เป็นทางเลือกหนึ่งที่สามารถแลกกับคุณค่าอื่นได้ตามเป้าหมายของงาน
2 ความคิดเห็น
นั่นแหละจึงเป็นเหตุผลว่าทำไมเราถึงยึดติดกับ abstraction กันนัก
ความคิดเห็นจาก Lobste.rs
น่าเสียดายที่ชื่อบทความต้นฉบับค่อนข้างชวนคลิก แต่เนื้อหาจริงใกล้กับประเด็นว่า เราควรสามารถทำงานให้คืบหน้าได้ แม้จะเข้าใจโค้ดเบสขนาดใหญ่เพียงบางส่วน
หากมองจากมุมของการสร้างทฤษฎี โดยถือว่าทฤษฎีมีทั้งความกว้างและความลึก ก็ไม่ได้ขัดกับใจความของบทความ ความกว้างหมายถึงการเข้าใจระบบในขอบเขตใดมากพอที่จะตอบคำถามและแก้ไขได้อย่างชำนาญ ส่วนความลึกหมายถึงความสามารถในการตอบคำถามที่ซับซ้อนแค่ไหนเกี่ยวกับส่วนเฉพาะ และทำการเปลี่ยนแปลงที่ซับซ้อนโดยยังรักษาความสมบูรณ์ถูกต้องไว้ได้
ถ้าเขียนโค้ดใหม่ทีละโมดูลพร้อมมีช่วงเปลี่ยนผ่าน ก็เท่ากับกำลังสร้างทฤษฎีที่แคบแต่ลึกเกี่ยวกับโมดูลนั้น แล้วทำงานตามทฤษฎีนั้น สำหรับฟังก์ชันเล็ก ๆ การเพิ่มพารามิเตอร์หรือค่าที่คืนกลับมาสักอย่างอาจไม่เป็นไร แต่เมื่อขนาดใหญ่ขึ้น การ เริ่มใหม่จากสภาพสะอาด แม้จะแค่บางโมดูล แล้วเชื่อมให้ส่วนอื่นเรียกใช้งาน implementation ใหม่ มักสมเหตุสมผลกว่า โดยพื้นฐานแล้ว แนวทางที่พยายามปรับปรุงความถูกต้องของ implementation ที่มีบั๊กมากแบบค่อยเป็นค่อยไปมักใช้ไม่ได้ผล และเรื่องนี้ก็มักใช้ได้กับคุณสมบัติอย่าง performance ด้วย
อย่างไรก็ตาม เมื่อ Naur กล่าวว่า “แทนที่จะปลุกโปรแกรมให้กลับมามีชีวิต ควรทิ้งข้อความโปรแกรมเดิม แล้วให้ทีมโปรแกรมเมอร์ใหม่แก้ปัญหาที่กำหนดตั้งแต่ต้น” ยังมีที่ให้ถกเถียงว่าเขาหมายถึงให้ลบโค้ดเดิมก่อนเริ่มเขียนใหม่ หรือให้ทิ้งได้หลังจากยืนยันแล้วว่าโปรแกรมใหม่เป็นตัวทดแทนที่เหมาะสม
ยิ่งไปกว่านั้น ในโลกจริง ตัวปัญหาที่ถูกกำหนดนั้นเองไม่ได้ถูกกำหนดไว้ Naur สมมติว่ายังมีนิยามปัญหาเดิมเหลืออยู่ แต่ในโค้ดเบสขนาดใหญ่มักไม่มี สิ่งที่ใกล้เคียงที่สุดมักเป็น test suite ดังนั้นจึงสามารถเปลี่ยนส่วนประกอบต่าง ๆ โดยยังทำให้เทสต์ผ่านต่อไปได้
ในยุคนั้นยังไม่มี continuous deployment ด้วย ทุกวันนี้ บริการต้องทำงานต่อเนื่องไปพร้อมกับที่เราต้องรับสาย on-call ตอบคำถาม และแก้บั๊กเร่งด่วน ดังนั้นการคำนวณต้นทุนและประโยชน์ของการเขียนใหม่จึงเปลี่ยนไปด้วย
ข้อโต้แย้งนี้มีบางส่วนที่สื่อออกมาได้ดี แต่ส่วนใหญ่รู้สึกว่าเป็นเรื่องชัดเจนอยู่แล้ว ในระบบที่ใหญ่พอ ความเข้าใจเพียงบางส่วนคือสภาพเดียวที่เป็นไปได้ แต่องค์กรก็ควรมุ่งหาความเข้าใจที่ลึกขึ้นอยู่เสมอ
นอกเหนือจากเหตุผลว่า “เราได้รับเงินให้ทำงาน” ซอฟต์แวร์ขนาดใหญ่มักทำให้ผู้ใช้พึงพอใจไม่ได้ หรือไม่บรรลุเป้าหมายทางธุรกิจ แม้แต่ Windows และ OS X ก็อาจมองได้ว่ากำลังผุพังจากความซับซ้อนที่สะสมมา
ถ้าฝ่ายบริหารสามารถทำให้ความซับซ้อนหายไปได้ราวกับเวทมนตร์ พวกเขาก็คงทำ เพียงแต่นี่ยังเป็นปัญหาด้าน software engineering ที่ยังแก้ไม่ตก และใกล้เคียงกับการที่ฝ่ายบริหารยอมรับการประนีประนอมเช่นนั้นภายใต้เงื่อนไขปัจจุบัน มากกว่าจะเป็นเพราะอยากปล่อยโค้ดแย่ ๆ
อาจมองได้ว่า “ถ้าเป็น monopoly ก็พอแล้ว ดังนั้นจะปล่อยซอฟต์แวร์ห่วย ๆ บั๊กเยอะก็ได้” แต่แบบนั้นเป็นมุมมองสิ้นหวังเกินไป มีบริษัทซอฟต์แวร์จำนวนมากที่ไม่ได้ผูกขาดหรือไม่สามารถกักผู้ใช้ไว้ได้ ดังนั้นสำหรับที่เหล่านั้น คุณภาพจึงสำคัญจริง ๆ
ภายใต้การตีความแบบนี้ แนวคิดเรื่องความเข้าใจก็ดูคล้ายบทบาทการเฝ้าประตูคัดคนอยู่บ้าง
แนวทางที่บทความอธิบายเกี่ยวข้องอย่างใกล้ชิดกับ ความสามารถในการให้เหตุผลแบบเฉพาะที่ กับบางส่วนของโค้ด
การให้เหตุผลแบบเฉพาะที่ ซึ่งหมายถึงการเข้าใจส่วนหนึ่งของโค้ดเบสขนาดใหญ่โดยไม่ต้องเข้าใจบริบทรอบข้างทั้งหมด เป็นแนวคิดหลักที่วิทยาการคอมพิวเตอร์ไล่ตามมาตั้งแต่ต้น
ข้อดีหลักของ structured programming คือทำให้ให้เหตุผลแบบเฉพาะที่ได้ และคำแนะนำให้หลีกเลี่ยงตัวแปร global ก็ส่วนใหญ่มีเป้าหมายเดียวกัน functional programming ทำให้ให้เหตุผลแบบเฉพาะที่ได้ด้วยการกำจัด side effect ส่วนวิธีที่ object-oriented programming ยึดเป็นหลักข้อหนึ่ง คือการผูกโครงสร้างข้อมูลเข้ากับโค้ดที่จัดการมัน ก็เป็นอีกวิธีหนึ่งในการให้เหตุผลแบบเฉพาะที่
พลังที่แท้จริงของแนวคิดพื้นฐานเหล่านี้อยู่ที่การทำให้เราสามารถให้เหตุผลและทำงานกับส่วนเล็ก ๆ ได้โดยไม่ต้องเข้าใจทั้งโค้ดเบส แม้จะไม่ใช่สถานการณ์ที่พึงประสงค์ก็ตาม
ผมอ่านแล้วมองว่าเป็นข้อโต้แย้งที่น่าสนใจต่อคำแนะนำว่า “ต้องเข้าใจทุกบรรทัดในโค้ดเบส” และเพราะประเด็นหลักของบทความเชื่อมโยงกับ แนวปฏิบัติในการพัฒนา จึงติดแท็ก
#practicesผมรู้ว่าชุมชนนี้ไม่ชอบ LLM แต่ผมยังสงสัยว่าบทความนี้เข้าข่าย
#vibecodingจริงหรือไม่vibecodingและแม้ผมจะไม่เห็นด้วย แต่นั่นคือธรรมเนียมปฏิบัติ คำถามหลักของบทความนี้ก็เกี่ยวพันอย่างใกล้ชิดกับ การเขียนโค้ดโดยมี LLM ช่วยอย่างไรก็ตาม ผมเห็นด้วยว่า
vibecodingไม่ควรเป็นแท็กเดียว บทความเพิ่งกล่าวถึง LLM อย่างชัดเจนในตอนท้าย และประเด็นหลักก็น่าสนใจและควรค่าแก่การถกเถียงตั้งแต่ยุคก่อน LLM แล้ว ดังนั้นผมเห็นว่ามีเหตุผลพอที่จะกู้แท็กpracticesกลับมา จึงกู้กลับมาเอง และแนะนำให้คนอื่นทำแบบเดียวกันแม้ในโลกที่การใช้ LLM อาจขัดขวางความเข้าใจอย่างสมบูรณ์ต่อโค้ดเบส มันก็ยังเกี่ยวข้องอยู่
ถ้าแท็กหมายถึง “อาจเกี่ยวข้องกับคนที่สนใจ vibe coding” ก็เหมาะสมแน่นอน แต่ถ้าหมายถึง “ไม่เกี่ยวข้องกับใครนอกจากคนที่สนใจ vibe coding” ก็ไม่เหมาะ แท็กอื่นทั้งหมดถูกใช้ในความหมายแบบแรก แต่ผู้ใช้ Lobsters จำนวนไม่น้อยใช้แท็กนี้เพียงแท็กเดียวในความหมายแบบหลัง สุดท้ายพวกเขาก็ย่อมพลาดบทความนี้ไป
อีกลักษณะหนึ่งของการพัฒนาสมัยใหม่ที่ต่างจากปี 1985 คือ แม้คุณจะกลายเป็นผู้เชี่ยวชาญของ โค้ดเบส 300,000 บรรทัด แล้ว สัปดาห์หน้าคุณก็อาจต้องไปทำงานกับโค้ดเบส 300,000 บรรทัดอีกชุดที่ต่างกันโดยสิ้นเชิง
โปรแกรมเมอร์มืออาชีพที่มีประสบการณ์คุ้นเคยกับการถูกส่งเข้าไปในพื้นที่ไม่รู้จักได้ทุกเมื่อ และพึ่งพาส่วนผสมของสำนวนร่วมกัน (Google C++ Style Guide), เครื่องมืออัตโนมัติอย่างคอมไพเลอร์ที่แจ้งข้อผิดพลาดเมื่อใช้ API ผิด และสัญชาตญาณว่าโปรแกรมขนาดใหญ่ “ควรถูกจัดโครงสร้างอย่างไร”
ผมเคยเห็นการถกเถียงทำนองว่า “ตอนนี้ไม่มีใครเข้าใจพฤติกรรมของทั้งโค้ดเบสแล้ว จะพัฒนาต่อได้อย่างไร?” เช่นในกรณี Bun ที่ถูกเขียนใหม่ด้วย LLM แต่นี่คล้ายกับการถามว่า ถ้าไม่ใช่นักเขียนแล้วจะเข้าใจนวนิยายได้อย่างไร สุดท้ายมันก็คือโค้ด จึงอ่านได้ ถ้าไม่เข้าใจฟังก์ชันไหน ก็แบ่งมันเป็นหลายส่วน เขียนเทสต์ลอง จด control flow ลงกระดาษ หรือทำอะไรก็ได้
เพราะเราต้องย้ายโปรเจ็กต์ไปมาเป็นประจำ จึงไม่มีเหตุผลต้องรักษาความเข้าใจต่อโค้ดเบสเก่าไว้ตลอด เมื่อถึงจุดหนึ่ง ทุกอย่างก็ปนกันคล้าย ๆ กันหมด ต่อให้ต้องช่วยให้โค้ด Scala ของสตาร์ทอัพที่บริษัทซื้อมา สื่อสารกับบริการ Ruby แบบ JSON ที่กำลังถูกเขียนใหม่เป็น Go ผ่านโปรโตคอล RPC แบบ Thrift ที่ปรับแต่งเอง การค้นหา
Scala syntax referenceกับThrift wire encodingสักชั่วโมงก็พอจะเริ่มต้นได้ไม่จำเป็นต้องเป็นผู้เชี่ยวชาญด้วย เพราะอีกหนึ่งเดือนถัดมา คุณอาจกำลังดีบักว่าทำไม type checker ที่ใช้ OCaml สำหรับ JavaScript ถึงชนใน implementation ของ Linux kernel ที่เขียนด้วย Go อยู่ก็ได้ สุดท้ายแล้วมันก็เป็นแค่โค้ดทั้งนั้น