The Tar Pit
Een schip op het strand is een baken in zee. [เรือที่เกยหาดคือประภาคารของท้องทะเล]
CR. Knight, Mural of La Brea Tar Pits The George C. Page Museum of La Brea Discoveries, The Natural History Museum of Los Angeles County
ไม่มีฉากใดจากยุคก่อนประวัติศาสตร์ที่จะตราตรึงใจไปกว่าภาพการดิ้นรนเพื่อเอาชีวิตรอดของเหล่าสัตว์ร้ายขนาดมหึมาในบ่อดินยางมะตอย (tar pits) ในจินตนาการเราเห็นไดโนเสาร์ แมมมอธ และเสือเขี้ยวดาบที่กำลังต่อสู้กับแรงยึดเหนี่ยวของยางมะตอย ยิ่งดิ้นรนรุนแรงเพียงใด ยางมะตอยก็ยิ่งพันตูมากขึ้นเท่านั้น และไม่มีสัตว์ตัวใดที่แข็งแกร่งหรือชาญฉลาดพอที่จะรอดพ้นจากการจมลงในที่สุด การเขียนโปรแกรมระบบขนาดใหญ่ (Large-system programming) ในช่วงทศวรรษที่ผ่านมาก็เป็นเหมือนบ่อดินยางมะตอยเช่นนั้น และสัตว์ร้ายที่ยิ่งใหญ่และทรงพลังหลายตัวก็ได้ดิ้นรนอย่างรุนแรงอยู่ในนั้น ส่วนใหญ่รอดออกมาพร้อมกับระบบที่ทำงานได้ แต่มีเพียงไม่กี่รายที่บรรลุเป้าหมาย ทำได้ตาม schedule และอยู่ในงบประมาณ ไม่ว่าจะทีมขนาดใหญ่หรือเล็ก มโหฬารหรือคล่องตัว ทีมแล้วทีมเล่าต่างก็ติดอยู่ในยางมะตอยนี้ ดูเหมือนไม่มีสิ่งใดเพียงอย่างเดียวที่เป็นสาเหตุของความยากลำบาก—เราอาจดึงเท้าข้างใดข้างหนึ่งออกมาได้ แต่การสะสมของปัจจัยหลายอย่างที่เกิดขึ้นพร้อมกันและส่งผลต่อกันกลับทำให้การเคลื่อนไหวยิ่งช้าลงเรื่อยๆ ทุกคนดูเหมือนจะตกใจกับความเหนียวแน่นของปัญหานี้ และมันยากที่จะแยกแยะธรรมชาติของมันออกมา แต่เราต้องพยายามทำความเข้าใจมันหากเราต้องการที่จะแก้ปัญหานี้
ดังนั้น ให้เราเริ่มต้นด้วยการระบุถึงทักษะฝีมือของ system programming ตลอดจนความสุขและความทุกข์ที่แฝงอยู่ในงานนี้กันเถอะ
The Programming Systems Product
บางครั้งเราอาจได้อ่านข่าวในหนังสือพิมพ์ว่า programmer สองคนในโรงรถที่ดัดแปลงใหม่สามารถสร้างโปรแกรมที่สำคัญซึ่งเหนือกว่าความพยายามอย่างเต็มที่ของทีมขนาดใหญ่ได้ และ programmer ทุกคนก็พร้อมที่จะเชื่อเรื่องเล่าเช่นนั้น เพราะเขารู้ดีว่าเขาสามารถสร้างโปรแกรมใดๆ ได้เร็วกว่าอัตรา 1,000 ประโยคคำสั่งต่อปี (1,000 statements/year) ที่มีรายงานสำหรับทีมในอุตสาหกรรมมากนัก ถ้าอย่างนั้น ทำไมทีมเขียนโปรแกรมในอุตสาหกรรมทั้งหมดถึงไม่ถูกแทนที่ด้วยคู่หูในโรงรถที่ทุ่มเทล่ะ? เราต้องพิจารณาถึงสิ่งที่กำลังถูกผลิตขึ้นมา ในมุมซ้ายบนของรูปที่ 1.1 คือ "โปรแกรม" (program) ซึ่งมีความสมบูรณ์ในตัวเอง พร้อมที่จะถูกรันโดยผู้เขียนบนระบบที่มันถูกพัฒนาขึ้นมา นั่นคือสิ่งที่มักจะถูกสร้างขึ้นในโรงรถ และนั่นคือสิ่งที่ programmer แต่ละคนใช้ในการประมาณการผลิตภาพ (productivity)
รูปที่ 1.1 วิวัฒนาการของผลิตภัณฑ์ระบบการเขียนโปรแกรม (programming systems product)
มีสองวิธีที่โปรแกรมจะถูกแปลงให้เป็นวัตถุที่มีประโยชน์มากขึ้น แต่ก็มีต้นทุนสูงขึ้นด้วย สองวิธีนี้แสดงด้วยขอบเขตในแผนภาพ หากข้ามขอบเขตแนวนอนลงมา โปรแกรมจะกลายเป็น "ผลิตภัณฑ์โปรแกรม" (programming product) นี่คือโปรแกรมที่ใครก็ตามสามารถนำไปรัน ทดสอบ ซ่อมแซม และขยายผลได้ มันสามารถใช้งานได้ในสภาพแวดล้อมการทำงาน (operating environments) ที่หลากหลาย สำหรับชุดข้อมูลหลายชุด การจะกลายเป็นผลิตภัณฑ์โปรแกรมที่ใช้งานได้ทั่วไปนั้น โปรแกรมจะต้องถูกเขียนขึ้นในรูปแบบที่เป็นสากล (generalized fashion) โดยเฉพาะอย่างยิ่ง ช่วงและรูปแบบของข้อมูลนำเข้า (inputs) จะต้องถูกทำให้เป็นสากลมากที่สุดเท่าที่อัลกอริทึมพื้นฐานจะเอื้ออำนวยได้อย่างสมเหตุสมผล จากนั้นโปรแกรมจะต้องผ่านการทดสอบอย่างละเอียดเพื่อให้สามารถเชื่อถือได้ ซึ่งหมายความว่าต้องมีการเตรียมคลัง test cases จำนวนมากที่สำรวจช่วงของข้อมูลนำเข้าและตรวจสอบขอบเขตของมัน รวมถึงต้องรันและบันทึกผลไว้ด้วย สุดท้าย การเลื่อนระดับจากโปรแกรมไปสู่ผลิตภัณฑ์โปรแกรมต้องมีการทำเอกสารประกอบ (documentation) ที่ละเอียด เพื่อให้ทุกคนสามารถใช้งาน แก้ไข และขยายผลมันได้ ตามกฎเกณฑ์คร่าวๆ ผมประมาณการว่าผลิตภัณฑ์โปรแกรมจะมีต้นทุนสูงกว่า debugged program ที่มีหน้าที่เดียวกันอย่างน้อยสามเท่า
หากข้ามขอบเขตแนวตั้งไป โปรแกรมจะกลายเป็นส่วนประกอบในระบบการเขียนโปรแกรม (component in a programming system) นี่คือกลุ่มของโปรแกรมที่โต้ตอบกัน มีการประสานหน้าที่กันและมีระเบียบในเรื่องรูปแบบ เพื่อให้การประกอบกันนั้นกลายเป็นสิ่งอำนวยความสะดวกที่สมบูรณ์สำหรับงานขนาดใหญ่ การจะกลายเป็นส่วนประกอบของระบบการเขียนโปรแกรมได้นั้น โปรแกรมจะต้องถูกเขียนขึ้นเพื่อให้ทุกข้อมูลนำเข้าและข้อมูลส่งออกเป็นไปตามไวยากรณ์ (syntax) และความหมาย (semantics) ที่มี interfaces ที่นิยามไว้อย่างแม่นยำ โปรแกรมจะต้องถูกออกแบบมาเพื่อให้ใช้ทรัพยากรตามงบประมาณที่กำหนดไว้เท่านั้น—ไม่ว่าจะเป็นพื้นที่หน่วยความจำ (memory space), อุปกรณ์รับเข้า-ส่งออก (input-output devices) หรือเวลาของคอมพิวเตอร์ สุดท้าย โปรแกรมจะต้องได้รับการทดสอบร่วมกับส่วนประกอบอื่นๆ ของระบบในทุกรูปแบบการผสมผสานที่คาดหวัง การทดสอบนี้ต้องครอบคลุมมาก เพราะจำนวนกรณีทดสอบจะเพิ่มขึ้นแบบทวีคูณ (combinatorially) และต้องใช้เวลามาก เพราะบั๊กที่ซ่อนอยู่อาจเกิดจากการโต้ตอบที่ไม่คาดคิดของส่วนประกอบที่ผ่านการแก้ไขข้อผิดพลาดแล้ว ส่วนประกอบของระบบการเขียนโปรแกรมมีต้นทุนสูงกว่า stand-alone program ที่มีหน้าที่เดียวกันอย่างน้อยสามเท่า และต้นทุนอาจสูงกว่านั้นหากระบบมีส่วนประกอบจำนวนมาก
ในมุมขวาล่างของรูปที่ 1.1 คือผลิตภัณฑ์ระบบการเขียนโปรแกรม (programming systems product) สิ่งนี้แตกต่างจากโปรแกรมธรรมดาในทุกๆ ด้านที่กล่าวมาข้างต้น และมีต้นทุนสูงถึงเก้าเท่า แต่มันคือวัตถุที่มีประโยชน์อย่างแท้จริง และเป็นผลิตภัณฑ์ที่ตั้งเป้าหมายไว้ของความพยายามในงาน system programming ส่วนใหญ่
The Joys of the Craft
ทำไมการเขียนโปรแกรมถึงสนุก? ผู้ปฏิบัติงานจะคาดหวังความเพลิดเพลินอะไรเป็นรางวัลได้บ้าง?
อย่างแรกคือความสุขบริสุทธิ์จากการได้สร้างสิ่งต่างๆ เช่นเดียวกับที่เด็กเพลิดเพลินกับการทำขนมเค้กจากโคลน ผู้ใหญ่เองก็สนุกกับการสร้างสิ่งต่างๆ โดยเฉพาะสิ่งที่เขาออกแบบเอง ผมคิดว่าความสุขนี้ต้องเป็นภาพสะท้อนความสุขของพระเจ้าในการสร้างสิ่งต่างๆ ซึ่งเป็นความเพลิดเพลินที่แสดงออกมาในความแตกต่างและแปลกใหม่ของใบไม้แต่ละใบและเกล็ดหิมะแต่ละชิ้น
อย่างที่สองคือความยินดีในการสร้างสิ่งที่มีประโยชน์ต่อผู้อื่น ลึกลงไปข้างใน เราต้องการให้ผู้อื่นใช้ผลงานของเราและพบว่ามันมีประโยชน์ ในแง่นี้ระบบการเขียนโปรแกรมก็ไม่ได้แตกต่างไปจากที่เสียบดินสอดินเหนียวชิ้นแรกของเด็กที่ทำ "สำหรับห้องทำงานของพ่อ"
อย่างที่สามคือความหลงใหลในการประดิษฐ์วัตถุที่ซับซ้อนเหมือนปริศนาซึ่งประกอบด้วยชิ้นส่วนที่เคลื่อนไหวและขบกันอยู่ แล้วเฝ้าดูพวกมันทำงานในวงจรที่ละเอียดอ่อน แสดงผลลัพธ์ที่เป็นไปตามหลักการที่วางไว้ตั้งแต่ต้น คอมพิวเตอร์ที่ถูกโปรแกรมไว้มีความน่าหลงใหลเหมือนกับเครื่องพินบอลหรือกลไกของตู้เพลงที่ถูกพัฒนาไปจนถึงขีดสุด
อย่างที่สี่คือความสุขจากการได้เรียนรู้อยู่เสมอ ซึ่งเกิดจากลักษณะงานที่ไม่ซ้ำซาก ไม่ว่าจะทางใดทางหนึ่ง ปัญหามักจะใหม่เสมอ และผู้แก้ปัญหาก็จะได้เรียนรู้บางอย่าง ไม่ว่าจะเป็นในเชิงปฏิบัติ เชิงทฤษฎี หรือทั้งสองอย่าง
สุดท้ายคือความเพลิดเพลินจากการทำงานในสื่อกลางที่จัดการได้ง่าย (tractable medium) นักเขียนโปรแกรมก็เหมือนกับกวีที่ทำงานห่างจาก "เนื้อสารทางความคิด" (pure thought-stuff) เพียงเล็กน้อยเท่านั้น เขาสร้างปราสาทในอากาศจากอากาศ สร้างสรรค์โดยการใช้จินตนาการ น้อยนักที่จะมีสื่อกลางในการสร้างสรรค์ใดที่ยืดหยุ่นขนาดนี้ ขัดเกลาและแก้ไขได้ง่าย และสามารถสร้างโครงสร้างทางความคิดที่ยิ่งใหญ่ได้รวดเร็ว (ดังที่เราจะได้เห็นในภายหลัง ความง่ายในการจัดการนี้ก็มีปัญหาในตัวของมันเองเช่นกัน) กระนั้นก็ตาม สิ่งที่สร้างขึ้นจากโปรแกรมนั้นต่างจากคำพูดของกวี ตรงที่มันเป็นจริงในแง่ที่ว่ามันเคลื่อนไหวและทำงานได้ ให้ผลลัพธ์ที่มองเห็นได้แยกจากตัวสิ่งที่สร้างขึ้นมาเอง มันพิมพ์ผลลัพธ์ วาดรูป สร้างเสียง ขยับแขนกล เวทมนตร์ของตำนานและตำนานได้กลายเป็นจริงในยุคสมัยของเรา เพียงแค่เราพิมพ์ "คาถา" ที่ถูกต้องลงบน...
...แผง keyboard แล้วหน้าจอแสดงผลก็จะกลับมีชีวิตขึ้นมา แสดงสิ่งต่างๆ ที่ไม่เคยมีอยู่จริงหรือไม่เคยแม้แต่จะเป็นไปได้
การเขียนโปรแกรมจึงเป็นเรื่องสนุก เพราะมันตอบสนองความปรารถนาในการสร้างสรรค์ที่ฝังรากลึกอยู่ในตัวเรา และสร้างความเพลิดเพลินให้กับสุนทรียภาพที่เรามีร่วมกันเฉกเช่นมนุษย์ทุกคน
The Woes of the Craft
อย่างไรก็ตาม ใช่ว่าทุกอย่างจะมีความสุข การรับรู้ถึงความทุกข์ที่แฝงอยู่จะช่วยให้เราอดทนต่อพวกมันได้ง่ายขึ้นเมื่อมันปรากฏขึ้น อย่างแรกคือ เราต้องทำทุกอย่างให้สมบูรณ์แบบ คอมพิวเตอร์มีความคล้ายคลึงกับเวทมนตร์ในตำนานในแง่นี้เช่นกัน หากตัวอักษรเพียงตัวเดียวหรือจังหวะการหยุดเพียงครั้งเดียวของคาถาไม่อยู่ในรูปแบบที่ถูกต้องอย่างเคร่งครัด เวทมนตร์ก็จะไม่ทำงาน มนุษย์เราไม่คุ้นเคยกับการทำตัวให้สมบูรณ์แบบ และมีกิจกรรมของมนุษย์เพียงไม่กี่ด้านที่เรียกร้องสิ่งนั้น การปรับตัวให้เข้ากับความต้องการความสมบูรณ์แบบ ผมคิดว่าเป็นส่วนที่ยากที่สุดในการเรียนรู้วิธีเขียนโปรแกรม
ถัดมาคือ การที่ผู้อื่นเป็นผู้กำหนดวัตถุประสงค์ จัดหาทรัพยากร และให้ข้อมูลแก่เรา เราแทบจะไม่สามารถควบคุมสถานการณ์ในการทำงาน หรือแม้กระทั่งเป้าหมายของมันได้เลย ในแง่ของการบริหารจัดการ อำนาจที่มีมักไม่เพียงพอต่อความรับผิดชอบที่ได้รับ อย่างไรก็ตาม ดูเหมือนว่าในทุกสาขาอาชีพ งานที่ทำได้สำเร็จมักจะไม่มีอำนาจอย่างเป็นทางการที่สมน้ำสมเนื้อกับความรับผิดชอบ ในทางปฏิบัติ อำนาจที่แท้จริง (ซึ่งตรงข้ามกับอำนาจอย่างเป็นทางการ) จะได้รับมาจากแรงขับเคลื่อนของความสำเร็จนั่นเอง
การต้องพึ่งพาผู้อื่นนั้นมีกรณีหนึ่งที่สร้างความเจ็บปวดเป็นพิเศษสำหรับนักเขียนโปรแกรมระบบ (system programmer) นั่นคือเขาต้องพึ่งพาโปรแกรมของคนอื่น ซึ่งมักจะถูกออกแบบมาไม่ดี มีการนำไปใช้งานที่แย่ ส่งมอบงานไม่ครบถ้วน (ไม่มี source code หรือ test cases) และมีเอกสารประกอบที่ย่ำแย่ ดังนั้นเขาจึงต้องเสียเวลาหลายชั่วโมงในการศึกษาและแก้ไขสิ่งต่างๆ ที่ในโลกอุดมคติควรจะสมบูรณ์ พร้อมใช้งาน และใช้งานได้จริง
ความทุกข์ประการถัดมาคือ การออกแบบแนวคิดที่ยิ่งใหญ่นั้นเป็นเรื่องสนุก แต่การตามหาบั๊กเล็กๆ น้อยๆ นั้นเป็นเพียงงานหนัก กิจกรรมการสร้างสรรค์ใดๆ มักมาพร้อมกับชั่วโมงที่น่าเบื่อหน่ายของการทำงานที่น่ารำคาญและต้องใช้ความพยายามอย่างยิ่งยวด และการเขียนโปรแกรมก็ไม่มีข้อยกเว้น
ถัดไปคือ การพบว่าการแก้ไขข้อผิดพลาด (debugging) มีการเข้าใกล้จุดสิ้นสุดแบบเชิงเส้น (linear convergence) หรือแย่กว่านั้น ในขณะที่เราแอบหวังว่าจะเข้าถึงจุดสิ้นสุดแบบยกกำลังสอง (quadratic) ดังนั้นการทดสอบจึงลากยาวออกไปเรื่อยๆ บั๊กที่ยากที่สุดในช่วงท้ายต้องใช้เวลาหามากกว่าบั๊กตัวแรกๆ มากนัก
ความทุกข์ประการสุดท้าย และบางครั้งก็เป็นฟางเส้นสุดท้าย คือการที่ผลิตภัณฑ์ที่เราทุ่มเทแรงกายแรงใจมาอย่างยาวนานดูเหมือนจะล้าสมัยไปแล้วในขณะที่ (หรือก่อนที่)...
...การเสร็จสมบูรณ์ เพื่อนร่วมงานและคู่แข่งต่างก็กำลังไล่ตามแนวคิดใหม่ๆ ที่ดีกว่าอยู่แล้ว การเข้ามาแทนที่ของ "ผลผลิตทางความคิด" ของเราไม่เพียงแต่ถูกวาดภาพไว้ แต่ยังถูกกำหนด schedule ไว้แล้วด้วย สิ่งนี้มักจะดูแย่กว่าความเป็นจริงเสมอ โดยทั่วไปแล้วผลิตภัณฑ์ใหม่ที่ดีกว่าจะยังไม่พร้อมใช้งานเมื่อเราทำผลิตภัณฑ์ของเราเสร็จ มันเป็นเพียงสิ่งที่ถูกพูดถึงเท่านั้น และมันเองก็ต้องใช้เวลาในการพัฒนาอีกหลายเดือน เสือตัวจริงไม่มีทางเทียบได้กับเสือกระดาษ เว้นแต่ว่าความต้องการใช้งานจริงจะเกิดขึ้น เมื่อนั้นคุณค่าของความเป็นจริงจะสร้างความพึงพอใจในแบบของมันเอง แน่นอนว่ารากฐานทางเทคโนโลยีที่เราสร้างงานขึ้นมานั้นก้าวหน้าอยู่เสมอ ทันทีที่เรา "แช่แข็ง" (freeze) การออกแบบ มันก็จะล้าสมัยในแง่ของแนวคิดทันที แต่การนำผลิตภัณฑ์จริงไปใช้งานนั้นต้องมีการจัดระยะแบ่งช่วง (phasing) และการกำหนดปริมาณ (quantizing) ความล้าสมัยของการนำไปใช้งานต้องวัดเทียบกับการนำไปใช้งานจริงอื่นๆ ที่มีอยู่ ไม่ใช่วัดเทียบกับแนวคิดที่ยังไม่เป็นรูปธรรม ความท้าทายและพันธกิจคือการค้นหาแนวทางแก้ไขที่แท้จริงสำหรับปัญหาที่เกิดขึ้นจริง ตาม schedule ที่เป็นไปได้จริง ด้วยทรัพยากรที่มีอยู่
นี่คือการเขียนโปรแกรม ซึ่งเป็นทั้งบ่อดินยางมะตอยที่ความพยายามมากมายต้องจมปลัก และเป็นกิจกรรมที่สร้างสรรค์ที่มีทั้งความสุขและความทุกข์ในแบบของมันเอง สำหรับหลายๆ คน ความสุขนั้นมีค่ามากกว่าความทุกข์อย่างมาก และสำหรับพวกเขาเหล่านั้น เนื้อหาส่วนที่เหลือของหนังสือเล่มนี้จะพยายามวาง "สะพานไม้" ทางเดินเพื่อข้ามผ่านบ่อยางมะตอยนี้ไปให้ได้