11 คะแนน โดย GN⁺ 10 시간 전 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • ระบบขนาดใหญ่ที่มีโค้ดนับสิบล้านบรรทัดเป็นสิ่งที่ไม่มีใครสามารถเก็บภาพรวมทั้งหมดไว้ในหัวได้ ดังนั้นวิศวกรจึงต้องสามารถทำงานได้อย่างมีประสิทธิภาพแม้มีเพียง ความเข้าใจที่ถูกต้องบางส่วน
  • งานเขียน 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 ความคิดเห็น

 
ndrgrd 48 분 전

นั่นแหละจึงเป็นเหตุผลว่าทำไมเราถึงยึดติดกับ 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 จริงหรือไม่

    • คุณอาจรู้อยู่แล้ว แต่ใน lobste.rs เนื้อหาทั้งหมดที่เกี่ยวข้องกับการใช้ LLM ถูกจัดหมวดหมู่อย่างกว้าง ๆ เป็น 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 อยู่ก็ได้ สุดท้ายแล้วมันก็เป็นแค่โค้ดทั้งนั้น