The Other Face

"สิ่งที่เราไม่เข้าใจ เราก็ไม่ได้เป็นเจ้าของมัน" — เกอเธ่ (GOETHE)

"โอ้ ขอผู้อธิบายที่เรียบง่ายให้ฉันเถิด ผู้ซึ่งไม่ทำให้สมองต้องเหนื่อยล้าด้วยการค้นคว้าที่ลึกซึ้งเกินไป" — แครบ (CRABBE)

ภาพจำลองของสโตนเฮนจ์ (Stonehenge) คอมพิวเตอร์ที่ไม่มีเอกสารประกอบขนาดใหญ่ที่สุดในโลก

โปรแกรมคอมพิวเตอร์คือข้อความจากมนุษย์ถึงเครื่องจักร ไวยากรณ์ที่ถูกจัดวางอย่างเข้มงวดและคำจำกัดความที่ละเอียดถี่ถ้วนล้วนมีอยู่เพื่อให้เจตนาชัดเจนต่อเครื่องยนต์ที่ไร้ชีวิต แต่โปรแกรมที่ถูกเขียนขึ้นยังมี "อีกด้านหนึ่ง" นั่นคือด้านที่บอกเล่าเรื่องราวของมันให้แก่ผู้ใช้ที่เป็นมนุษย์ แม้แต่โปรแกรมที่เป็นส่วนตัวที่สุด การสื่อสารเช่นนี้ก็ยังจำเป็น เพราะความทรงจำของผู้เขียนซึ่งเป็นผู้ใช้ด้วยอาจล้มเหลว และเขาต้องการการรื้อฟื้นรายละเอียดในผลงานของตนเอง และเอกสารประกอบจะยิ่งทวีความสำคัญขึ้นอีกเพียงใดสำหรับโปรแกรมสาธารณะ ซึ่งผู้ใช้อยู่ห่างไกลจากผู้เขียนทั้งในแง่ของเวลาและสถานที่! สำหรับผลิตภัณฑ์โปรแกรม อีกด้านหนึ่งที่หันหาผู้ใช้มีความสำคัญเท่าเทียมกับด้านที่หันหาเครื่องจักรทุกประการ

พวกเราส่วนใหญ่มักจะแอบตำหนิผู้เขียนที่อยู่ห่างไกลและไม่เปิดเผยนามของโปรแกรมที่มีเอกสารประกอบเพียงน้อยนิด และพวกเราหลายคนจึงพยายามปลูกฝังทัศนคติเรื่องการทำเอกสารประกอบให้แก่นักเขียนโปรแกรมหน้าใหม่ เพื่อให้เป็นแรงบันดาลใจไปตลอดชีวิต เอาชนะความขี้เกียจและความกดดันจากกำหนดการ แต่โดยรวมแล้วเราล้มเหลว ผมคิดว่าเราใช้วิธีที่ผิด

Thomas J. Watson ผู้พ่อ เคยเล่าเรื่องประสบการณ์ครั้งแรกของเขาในฐานะพนักงานขายเครื่องคิดเลขในตอนเหนือของรัฐนิวยอร์ก ด้วยความกระตือรือร้นเต็มเปี่ยม เขาออกไปพร้อมกับรถลากที่บรรทุกเครื่องคิดเลขมาเต็มคัน เขาทำงานในเขตของเขาอย่างขยันขันแข็งแต่กลับขายไม่ได้เลยสักเครื่องเดียว ด้วยความท้อแท้เขารายงานต่อบอสของเขา ผู้จัดการฝ่ายขายฟังอยู่ครู่หนึ่งแล้วพูดว่า "มาช่วยผมยกเครื่องคิดเลขขึ้นรถ ผูกอานม้า แล้วเราไปกันอีกรอบ" พวกเขาทำตามนั้น และทั้งคู่ได้ไปพบลูกค้าทีละราย โดยชายผู้อาวุโสกว่าแสดงให้เห็นว่า "ขายเครื่องคิดเลขอย่างไร" หลักฐานทั้งหมดบ่งชี้ว่าเขาได้รับบทเรียนนั้นอย่างถ่องแท้

เป็นเวลาหลายปีที่ผมบรรยายในชั้นเรียนวิศวกรรมซอฟต์แวร์อย่างขยันขันแข็งเกี่ยวกับความจำเป็นและความเหมาะสมของการทำเอกสารประกอบที่ดี โดยพยายามเกลี้ยกล่อมพวกเขาอย่างร้อนรนและสละสลวยมากขึ้นเรื่อยๆ แต่มันไม่ได้ผล ผมสันนิษฐานเอาเองว่าพวกเขาเรียนรู้วิธีการทำเอกสารประกอบที่ถูกต้องแล้ว และล้มเหลวเพราะขาดความกระตือรือร้น จากนั้นผมจึงลอง "ยกเครื่องคิดเลขขึ้นรถลาก" นั่นคือแสดงให้พวกเขาเห็นว่า "งานนี้ทำอย่างไร" และนั่นประสบความสำเร็จมากกว่ามาก ดังนั้นส่วนที่เหลือของบทความนี้จะลดการเกลี้ยกล่อมลง และมุ่งเน้นไปที่ "วิธีการ" ของการทำเอกสารประกอบที่ดี

What Documentation Is Required?

เอกสารประกอบในระดับที่แตกต่างกันเป็นสิ่งจำเป็นสำหรับผู้ใช้งานทั่วไปของโปรแกรม, สำหรับผู้ใช้ที่ต้องพึ่งพาโปรแกรมนั้น และสำหรับผู้ใช้ที่ต้องปรับปรุงโปรแกรมเพื่อรองรับการเปลี่ยนแปลงในสถานการณ์หรือจุดประสงค์

สำหรับการใช้งานโปรแกรม (To use a program): ผู้ใช้ทุกคนต้องการคำอธิบายโปรแกรมที่เป็นร้อยแก้ว เอกสารส่วนใหญ่มักล้มเหลวเพราะให้ภาพรวมน้อยเกินไป มีการอธิบายต้นไม้แต่ละต้น มีการให้ความเห็นที่เปลือกไม้และใบไม้ แต่กลับไม่มี "แผนที่ของป่า" เลย ในการเขียนคำอธิบายที่เป็นร้อยแก้วให้มีประโยชน์ ให้ถอยออกมามองภาพกว้างแล้วค่อยๆ ลงรายละเอียด:

  1. จุดประสงค์ (Purpose): หน้าที่หลักคืออะไร เหตุผลที่มีโปรแกรมนี้คืออะไร?
  2. สภาพแวดล้อม (Environment): มันจะรันบนเครื่องรุ่นไหน การกำหนดค่าฮาร์ดแวร์และระบบปฏิบัติการแบบใด?
  3. โดเมนและเรนจ์ (Domain and range): โดเมนของอินพุตที่ถูกต้องคืออะไร? เรนจ์ของเอาต์พุตที่สามารถปรากฏออกมาได้คืออะไร?
  4. ฟังก์ชันและการใช้อัลกอริทึม (Functions realized and algorithms used): มันทำงานอะไรอย่างแม่นยำ?
  5. รูปแบบอินพุต-เอาต์พุต (Input-output formats): ต้องแม่นยำและครบถ้วน
  6. คำแนะนำการใช้งาน (Operating instructions): รวมถึงพฤติกรรมเมื่อจบการทำงานแบบปกติและแบบผิดปกติ ตามที่ปรากฏที่คอนโซลและที่เอาต์พุต
  7. ตัวเลือก (Options): ผู้ใช้มีทางเลือกอะไรบ้างเกี่ยวกับฟังก์ชันการทำงาน?
  8. วิธีการระบุทางเลือกเหล่านั้นอย่างแน่ชัด
  9. เวลารัน (Running time): ใช้เวลานานเท่าใดสำหรับปัญหาขนาดที่กำหนดบนการกำหนดค่าที่ระบุ?
  10. ความแม่นยำและการตรวจสอบ (Accuracy and checking): คำตอบที่คาดหวังมีความแม่นยำเพียงใด? มีวิธีการตรวจสอบความแม่นยำแบบใดรวมอยู่ด้วย?

บ่อยครั้งที่ข้อมูลทั้งหมดนี้สามารถเขียนจบได้ภายในสามหรือสี่หน้า ซึ่งต้องการความเอาใจใส่อย่างมากในเรื่องความกระชับและความแม่นยำ

เนื้อหาส่วนใหญ่ของเอกสารฉบับนี้ควรถูกร่างขึ้น "ก่อน" ที่โปรแกรมจะถูกเขียน เพราะมันได้รวบรวมการตัดสินใจในการวางแผนเบื้องต้นเอาไว้

สำหรับการสร้างความเชื่อมั่นในโปรแกรม (To believe a program): คำอธิบายวิธีการใช้งานจะต้องเสริมด้วยคำอธิบายว่าเราจะรู้ได้อย่างไรว่าโปรแกรมกำลังทำงานได้อย่างถูกต้อง ซึ่งหมายถึงกรณีทดสอบ (test cases)

โปรแกรมทุกชุดที่ส่งมอบควรมีกรณีทดสอบขนาดเล็กบางกรณีที่ผู้ใช้สามารถรันได้ตามปกติเพื่อความสบายใจว่าเขามีสำเนาโปรแกรมที่ถูกต้องและโหลดเข้าเครื่องได้อย่างแม่นยำ จากนั้นเราจำเป็นต้องมีกรณีทดสอบที่ถี่ถ้วนมากขึ้น ซึ่งโดยปกติจะรันเฉพาะหลังจากที่มีการแก้ไขโปรแกรมแล้วเท่านั้น สิ่งเหล่านี้แบ่งออกเป็นสามส่วนตามโดเมนของข้อมูลอินพุต:

  1. กรณีเส้นทางหลัก (Mainline cases): ทดสอบฟังก์ชันหลักของโปรแกรมด้วยข้อมูลที่พบบ่อย
  2. กรณีที่เกือบจะถูกต้อง (Barely legitimate cases): ตรวจสอบขอบเขตของโดเมนอินพุต เพื่อรับประกันว่าค่าที่มากที่สุดเท่าที่เป็นไปได้ ค่าที่น้อยที่สุด และข้อยกเว้นที่ถูกต้องทุกรูปแบบสามารถทำงานได้
  3. กรณีที่เกือบจะไม่ถูกต้อง (Barely illegitimate cases): ตรวจสอบขอบเขตโดเมนจากอีกฝั่งหนึ่ง เพื่อรับประกันว่าอินพุตที่ไม่ถูกต้องจะทำให้เกิดข้อความวินิจฉัยที่เหมาะสม

สำหรับการแก้ไขโปรแกรม (To modify a program): การปรับปรุงโปรแกรมหรือการซ่อมแซมบั๊กต้องการข้อมูลที่มากกว่านั้นมาก แน่นอนว่ารายละเอียดที่ครบถ้วนเป็นสิ่งจำเป็น ซึ่งบรรจุอยู่ในรายการโปรแกรมที่มีการให้ความเห็นอย่างดี (well-commented listing) สำหรับผู้ที่จะทำการแก้ไข สิ่งที่ต้องการอย่างยิ่งคือภาพรวมที่ชัดเจนและเฉียบคมของ "โครงสร้างภายใน" อะไรคือส่วนประกอบของภาพรวมดังกล่าว?

  1. ผังงาน (flow chart) หรือกราฟโครงสร้างของโปรแกรมย่อย เราจะพูดถึงเรื่องนี้ในภายหลัง

  2. คำอธิบายอัลกอริทึมที่ใช้โดยละเอียด หรือการอ้างอิงถึงคำอธิบายดังกล่าวในเอกสารทางวิชาการ

  3. คำอธิบายการจัดวาง (layout) ของไฟล์ทั้งหมดที่ใช้

  4. ภาพรวมของโครงสร้างขั้นตอนการประมวลผล (pass structure) — ลำดับที่ข้อมูลหรือโปรแกรมถูกดึงมาจากเทปหรือดิสก์ — และสิ่งที่ทำสำเร็จในแต่ละขั้นตอน

  5. การอภิปรายถึงการแก้ไขที่คาดการณ์ไว้ในการออกแบบดั้งเดิม ลักษณะและตำแหน่งของจุดเชื่อมต่อ (hooks) และจุดออก (exits) รวมถึงการอภิปรายถึงแนวคิดของผู้เขียนดั้งเดิมว่าการแก้ไขรูปแบบใดที่อาจเป็นที่ต้องการและจะดำเนินการอย่างไร ข้อสังเกตของเขาเกี่ยวกับกับดักที่ซ่อนอยู่ (hidden pitfalls) ก็มีประโยชน์เช่นกัน

The Flow-Chart Curse

ผังงาน (flow chart) เป็นเอกสารประกอบโปรแกรมที่ถูกยกยอเกินความเป็นจริงอย่างมาก โปรแกรมจำนวนมากไม่จำเป็นต้องมีผังงานเลย และมีโปรแกรมเพียงไม่กี่โปรแกรมที่ต้องการผังงานที่มีความยาวมากกว่าหนึ่งหน้า

รูปที่ 15.1 กราฟโครงสร้างโปรแกรม

ผังงานแสดงโครงสร้างการตัดสินใจของโปรแกรม ซึ่งเป็นเพียงแง่มุมเดียวของโครงสร้างทั้งหมด พวกมันแสดงโครงสร้างการตัดสินใจได้ค่อนข้างสง่างามเมื่อผังงานจบลงในหน้าเดียว แต่ภาพรวมจะพังทลายลงทันทีเมื่อมีหลายหน้า ซึ่งเชื่อมต่อกันด้วยจุดออกและจุดเชื่อมต่อที่มีตัวเลขกำกับ

ผังงานหน้าเดียวสำหรับโปรแกรมที่มีเนื้อหาพอสมควร จะกลายเป็นแผนภาพโครงสร้างโปรแกรมและขั้นตอนต่างๆ ไปโดยปริยาย ในฐานะที่เป็นเช่นนั้น มันจึงมีประโยชน์มาก รูปที่ 15.1 แสดงกราฟโครงสร้างของโปรแกรมย่อยดังกล่าว แน่นอนว่ากราฟโครงสร้างเช่นนี้ไม่จำเป็นต้องทำตามมาตรฐานผังงานของ ANSI ที่ยุ่งยากเลย กฎเกณฑ์ทั้งหมดเกี่ยวกับรูปทรงกล่อง จุดเชื่อมต่อ การให้หมายเลข ฯลฯ จำเป็นก็ต่อเมื่อต้องการทำให้ผังงานที่ละเอียดมากๆ นั้นพอจะอ่านรู้เรื่องเท่านั้น

อย่างไรก็ตาม ผังงานที่ลงลึกในทุกรายละเอียดคือสิ่งที่ล้าสมัยและน่ารำคาญ เหมาะสำหรับการสอนผู้เริ่มต้นให้เริ่มคิดเป็นอัลกอริทึมเท่านั้น เมื่อตอนที่ Goldstine และ von Neumann นำเสนอเรื่องนี้ กล่องเล็กๆ และเนื้อหาภายในทำหน้าที่เสมือนเป็นภาษาระดับสูง ที่ช่วยจัดกลุ่มคำสั่งภาษาเครื่องที่อ่านไม่รู้เรื่องให้กลายเป็นกลุ่มที่มีความหมาย ดังที่ Iverson ได้ตระหนักตั้งแต่ช่วงแรกๆ ว่า ในภาษาระดับสูงที่เป็นระบบ การจัดกลุ่มนี้ได้ถูกทำไปเรียบร้อยแล้ว และแต่ละกล่องก็บรรจุเพียงหนึ่งคำสั่งเท่านั้น (รูปที่ 15.2) เมื่อเป็นเช่นนั้น ตัวกล่องเองก็ไม่เป็นอะไรมากไปกว่าการฝึกหัดการร่างภาพที่น่าเบื่อและสิ้นเปลืองพื้นที่ ซึ่งควรจะกำจัดทิ้งไปเสีย เมื่อทำเช่นนั้น ก็จะไม่มีอะไรเหลือนอกจากลูกศร ซึ่งลูกศรที่เชื่อมคำสั่งหนึ่งไปยังคำสั่งถัดไปนั้นซ้ำซ้อน ก็จงลบพวกมันทิ้งเสีย นั่นจะเหลือเพียง GO TO และหากใครปฏิบัติตามแนวทางที่ดีและใช้โครงสร้างแบบบล็อกเพื่อลด GO TO ให้เหลือน้อยที่สุด ลูกศรที่เหลืออยู่เพียงไม่กี่อันจะช่วย...

ความเข้าใจได้อย่างมหาศาล เราอาจจะวาดพวกมันลงในรายการโปรแกรมโดยตรงและยกเลิกผังงานไปได้เลย อันที่จริง การทำผังงานเป็นเรื่องที่ถูกพร่ำสอนมากกว่าจะถูกนำไปปฏิบัติจริง ผมไม่เคยเห็นนักเขียนโปรแกรมที่มีประสบการณ์คนไหนทำผังงานที่ละเอียดเป็นประจำก่อนจะเริ่มเขียนโปรแกรมเลย ในที่ที่มาตรฐานองค์กรบังคับให้มีผังงาน สิ่งเหล่านี้มักจะถูกทำขึ้น "หลังจาก" งานเสร็จแล้วแทบทั้งสิ้น หลายหน่วยงานภูมิใจกับการใช้โปรแกรมคอมพิวเตอร์เพื่อสร้าง "เครื่องมือออกแบบที่ขาดไม่ได้" นี้ขึ้นมาจากโค้ดที่เขียนเสร็จแล้ว ผมคิดว่าประสบการณ์ที่เป็นสากลนี้ไม่ใช่การออกนอกลู่นอกทางที่น่าอับอายและน่าสลดใจจากการปฏิบัติที่ดี ซึ่งต้องยอมรับด้วยเสียงหัวเราะอย่างประหม่า ทว่ามันคือการประยุกต์ใช้ดุลยพินิจที่ดี และมันสอนอะไรบางอย่างเราเกี่ยวกับประโยชน์ของผังงาน อัครสาวกเปโตรกล่าวถึงผู้เปลี่ยนความเชื่อใหม่ที่เป็นชาวต่างชาติและกฎหมายของยิวไว้ว่า "เหตุใดจึงวางภาระลงบนหลังของ [พวกเขา] ซึ่งทั้งบรรพบุรุษของเราและตัวเราเองก็ไม่สามารถแบกรับได้?" (กิจการ 15:10) ผมอยากจะกล่าวเช่นเดียวกันเกี่ยวกับนักเขียนโปรแกรมหน้าใหม่และแนวทางปฏิบัติที่ล้าสมัยของการทำผังงาน

Self-Documenting Programs

หลักการพื้นฐานของการประมวลผลข้อมูลสอนเราถึงความเขลาของการพยายามรักษาไฟล์ที่แยกจากกันให้สอดประสานกันอยู่เสมอ การรวมพวกมันเข้าเป็นไฟล์เดียวโดยที่แต่ละบันทึกข้อมูลบรรจุข้อมูลทั้งหมดที่ทั้งสองไฟล์มีเกี่ยวกับคีย์ที่กำหนดนั้นดีกว่ามาก ทว่าในทางปฏิบัติของการทำเอกสารประกอบโปรแกรม เรากลับละเมิดคำสอนของตนเอง โดยปกติเราพยายามที่จะรักษาโปรแกรมในรูปแบบที่เครื่องอ่านได้ควบคู่ไปกับชุดเอกสารที่มนุษย์อ่านได้ซึ่งประกอบด้วยร้อยแก้วและผังงาน ผลลัพธ์ที่ได้ก็ยืนยันคำสอนของเราเกี่ยวกับความเขลาของการแยกไฟล์ออกจากกัน เอกสารประกอบโปรแกรมนั้นมีชื่อเสียงในทางที่แย่ และการบำรุงรักษาเอกสารเหล่านั้นก็ยิ่งแย่กว่า การเปลี่ยนแปลงใดๆ ที่ทำในโปรแกรมมักจะไม่ปรากฏในเอกสารอย่างรวดเร็ว แม่นยำ และสม่ำเสมอ

ทางแก้ผมคิดว่าคือการรวมไฟล์เหล่านั้นเข้าด้วยกัน โดยนำเอกสารประกอบเข้าไปรวมไว้ในซอร์สโปรแกรม (source program) นี่เป็นทั้งแรงจูงใจที่ทรงพลังต่อการบำรุงรักษาที่ถูกต้อง และเป็นการรับประกันว่าเอกสารประกอบจะอยู่ใกล้ตัวผู้ใช้โปรแกรมเสมอ โปรแกรมประเภทนี้เรียกว่า "ทำเอกสารประกอบในตัว" (self-documenting) แน่นอนว่าสิ่งนี้จะดูเก้งก้าง (แต่ใช่ว่าเป็นไปไม่ได้) หากต้องรวมผังงานเข้าไปด้วย แต่เมื่อยอมรับว่าผังงานนั้นล้าสมัยและการใช้ภาษาระดับสูงเป็นหลัก การรวมโปรแกรมและเอกสารเข้าด้วยกันจึงเป็นเรื่องที่สมเหตุสมผล

การใช้ซอร์สโปรแกรมเป็นสื่อกลางในการทำเอกสารประกอบอาจมีข้อจำกัดบางประการ ในทางกลับกัน การที่ผู้อ่านเอกสารสามารถเข้าถึงซอร์สโปรแกรมได้บรรทัดต่อบรรทัดอย่างใกล้ชิดจะช่วยให้เกิดเทคนิคใหม่ๆ ได้ ถึงเวลาแล้วที่จะคิดค้นแนวทางและวิธีการใหม่ๆ อย่างถอนรากถอนโคนสำหรับการทำเอกสารประกอบโปรแกรม

เป้าหมายหลักคือ เราต้องพยายามลดภาระของการทำเอกสารประกอบ ภาระที่ทั้งเราและบรรพบุรุษของเราไม่สามารถจะ...

จะแบกรับได้สำเร็จ

แนวทาง (An approach): แนวคิดแรกคือการใช้ส่วนประกอบของโปรแกรมที่ต้องมีอยู่แล้วตามเหตุผลของภาษาโปรแกรม ให้บรรจุเอกสารประกอบไว้ให้มากที่สุด ดังนั้น ป้ายชื่อ (labels) คำสั่งประกาศตัวแปร และชื่อสัญลักษณ์ต่างๆ ล้วนถูกนำมาใช้เพื่อสื่อความหมายให้ได้มากที่สุดแก่ผู้อ่าน

แนวคิดที่สองคือการใช้พื้นที่ว่างและรูปแบบ (format) ให้มากที่สุดเท่าที่เป็นไปได้เพื่อเพิ่มความสามารถในการอ่านและแสดงความสัมพันธ์ของการเป็นส่วนย่อยหรือการซ้อนกัน (nesting)

แนวคิดที่สามคือการแทรกเอกสารร้อยแก้วที่จำเป็นลงในโปรแกรมในรูปแบบของย่อหน้าความเห็น (paragraph comments) โปรแกรมส่วนใหญ่มักจะมีความเห็นแบบบรรทัดต่อบรรทัดเพียงพออยู่แล้ว ส่วนโปรแกรมที่สร้างขึ้นเพื่อให้ตรงตามมาตรฐานองค์กรที่เข้มงวดสำหรับ "เอกสารที่ดี" มักจะมีความเห็นมากเกินไป ทว่าแม้แต่โปรแกรมเหล่านี้ก็มักจะขาดแคลนย่อหน้าความเห็นซึ่งให้ความเข้าใจและภาพรวมแก่ภาพรวมทั้งหมดจริงๆ

เนื่องจากเอกสารประกอบถูกสร้างขึ้นในโครงสร้าง การตั้งชื่อ และรูปแบบของโปรแกรม เนื้อหาส่วนใหญ่จึงต้องทำตั้งแต่ตอนเริ่มเขียนโปรแกรมครั้งแรก และนั่นก็คือเวลาที่มันควรจะถูกเขียนขึ้น เนื่องจากแนวทางการทำเอกสารในตัวช่วยลดงานส่วนเกิน จึงมีอุปสรรคน้อยลงในการลงมือทำตั้งแต่ตอนนั้น

เทคนิคบางประการ (Some techniques): รูปที่ 15.3 แสดงโปรแกรม PL/I ที่ทำเอกสารประกอบในตัว ตัวเลขในวงกลมไม่ใช่ส่วนหนึ่งของโปรแกรม แต่เป็นส่วนอ้างอิงสำหรับการอภิปรายนี้:

  1. ใช้ชื่อจ็อบแยกกันสำหรับการรันแต่ละครั้ง และบันทึกปูมการรันที่แสดงว่าได้ทดลองอะไร เมื่อไหร่ และผลลัพธ์เป็นอย่างไร หากชื่อประกอบด้วยส่วนที่ช่วยจำ (ในที่นี้คือ QLT) และคำต่อท้ายเป็นตัวเลข (ในที่นี้คือ 4) คำต่อท้ายสามารถใช้เป็นหมายเลขรอบการรัน เพื่อเชื่อมโยงรายการโปรแกรมและปูมเข้าด้วยกัน เทคนิคนี้ต้องการบัตรสั่งงานใหม่สำหรับการรันแต่ละครั้ง แต่สามารถทำเป็นชุดๆ ได้โดยการคัดลอกข้อมูลส่วนที่เหมือนกัน

  2. ใช้ชื่อโปรแกรมที่ช่วยจำแต่ระบุเวอร์ชันด้วย นั่นคือ ให้สมมติว่าจะมีหลายเวอร์ชัน ในที่นี้ตัวบ่งชี้คือเลขหลักสุดท้ายของปี 1967

  3. รวมคำอธิบายร้อยแก้วเป็นความเห็นในส่วนของ PROCEDURE

  4. อ้างถึงเอกสารมาตรฐานเพื่ออธิบายอัลกอริทึมพื้นฐานในทุกที่ที่เป็นไปได้ วิธีนี้ช่วยประหยัดพื้นที่ และมักจะชี้ไปยังคำอธิบายที่สมบูรณ์กว่าที่เราจะเขียนเองได้ และช่วยให้ผู้อ่านที่มีความรู้สามารถข้ามส่วนนั้นไปได้ด้วยความมั่นใจว่าเขาเข้าใจคุณแล้ว

  5. แสดงความสัมพันธ์กับอัลกอริทึมในหนังสือ: ก) การเปลี่ยนแปลง ข) การระบุกรณีเฉพาะ ค) การแสดงแทนข้อมูล

  6. ประกาศตัวแปรทั้งหมด โดยใช้ชื่อที่ช่วยจำ ใช้ความเห็นเพื่อเปลี่ยน DECLARE ให้เป็นคำอธิบายที่สมบูรณ์ สังเกตว่ามันมีชื่อและคำอธิบายโครงสร้างอยู่แล้ว เพียงแค่เสริมคำอธิบายวัตถุประสงค์เข้าไป การทำเช่นนี้ที่จุดเดียวจะช่วยให้ไม่ต้องทำซ้ำชื่อและคำอธิบายโครงสร้างในที่อื่นแยกต่างหาก

  7. ทำเครื่องหมายส่วนการเริ่มต้น (initialization) ด้วยป้ายชื่อ (label)

  8. ให้ป้ายชื่อแก่กลุ่มคำสั่ง เพื่อแสดงความสอดคล้องกับคำสั่งในคำอธิบายอัลกอริทึมที่มีอยู่ในเอกสารอ้างอิง

  9. ใช้การย่อหน้า (indenting) เพื่อแสดงโครงสร้างและการจัดกลุ่ม

  10. เพิ่มลูกศรแสดงทิศทางตรรกะลงในรายการโปรแกรมด้วยมือ สิ่งเหล่านี้มีประโยชน์มากในการแก้ไขข้อผิดพลาดและการเปลี่ยนแปลง สามารถรวมไว้ที่ขอบด้านขวาของพื้นที่ความเห็น และทำให้เป็นส่วนหนึ่งของข้อความที่เครื่องอ่านได้

  11. ใช้ความเห็นบรรทัดต่อบรรทัด หรือหมายเหตุถึงสิ่งที่ไม่ชัดเจน หากใช้เทคนิคข้างต้น ความเห็นเหล่านี้จะสั้นและมีจำนวนน้อยกว่าปกติ

  12. วางหลายคำสั่งไว้ในบรรทัดเดียว หรือหนึ่งคำสั่งในหลายบรรทัด เพื่อให้สอดคล้องกับการจัดกลุ่มความคิดและแสดงความสัมพันธ์กับคำอธิบายอัลกอริทึมอื่นๆ

รูปที่ 15.3 โปรแกรมที่ทำเอกสารประกอบในตัว

ทำไมจะไม่ล่ะ? อะไรคือข้อเสียของแนวทางการทำเอกสารประกอบเช่นนี้? มีข้อเสียอยู่หลายประการซึ่งเคยเป็นเรื่องจริงในอดีต แต่กำลังกลายเป็นเพียงจินตนาการตามยุคสมัยที่เปลี่ยนไป

ข้อโต้แย้งที่ร้ายแรงที่สุดคือการเพิ่มขึ้นของขนาดซอร์สโค้ดที่ต้องจัดเก็บ เมื่อสายงานนี้มุ่งไปสู่การจัดเก็บซอร์สโค้ดแบบออนไลน์มากขึ้นเรื่อยๆ เรื่องนี้จึงกลายเป็นปัจจัยที่ต้องพิจารณามากขึ้น ผมพบว่าตัวเองเขียนความเห็นสั้นลงในโปรแกรม APL ซึ่งจะถูกเก็บไว้ในดิสก์ เมื่อเทียบกับโปรแกรม PL/I ที่ผมจะเก็บไว้ในรูปแบบบัตรสั่งงาน

อย่างไรก็ตาม ในขณะเดียวกันเราก็กำลังมุ่งไปสู่การจัดเก็บเอกสารร้อยแก้วแบบออนไลน์เพื่อการเข้าถึงและการอัปเดตผ่านการแก้ไขข้อความด้วยคอมพิวเตอร์เช่นกัน...

ดังที่แสดงไว้ด้านบน การรวมร้อยแก้วและโปรแกรมเข้าด้วยกันช่วยลดจำนวนตัวอักษรทั้งหมดที่ต้องจัดเก็บลงได้

คำตอบทำนองเดียวกันนี้ใช้กับข้อโต้แย้งที่ว่าโปรแกรมที่ทำเอกสารในตัวต้องการการพิมพ์ที่มากกว่า เอกสารที่พิมพ์แยกต่างหากต้องการการกดแป้นพิมพ์อย่างน้อยหนึ่งครั้งต่อหนึ่งตัวอักษรต่อหนึ่งฉบับร่าง แต่โปรแกรมที่ทำเอกสารในตัวมีจำนวนตัวอักษรรวมน้อยกว่า และยังมีการกดแป้นพิมพ์ต่อตัวอักษรน้อยกว่าด้วย เนื่องจากไม่ต้องพิมพ์ฉบับร่างใหม่ทั้งหมด

แล้วเรื่องผังงานและกราฟโครงสร้างล่ะ? หากเราใช้เพียงกราฟโครงสร้างระดับสูงสุด มันอาจจะถูกเก็บไว้เป็นเอกสารแยกต่างหากได้อย่างปลอดภัย เพราะมันไม่ได้เปลี่ยนแปลงบ่อยนัก แต่แน่นอนว่ามันสามารถรวมไว้ในซอร์สโปรแกรมในรูปแบบของความเห็นได้ และนั่นดูจะเป็นทางเลือกที่ฉลาด

เทคนิคที่ใช้ข้างต้นสามารถนำไปใช้กับโปรแกรมภาษาแอสเซมบลีได้มากน้อยเพียงใด? ผมคิดว่าแนวทางพื้นฐานของการทำเอกสารในตัวนั้นสามารถนำมาปรับใช้ได้ทั้งหมด เพียงแต่พื้นที่และรูปแบบนั้นมีความเป็นอิสระน้อยกว่า จึงไม่สามารถใช้ได้อย่างยืดหยุ่นนัก ชื่อและการประกาศโครงสร้างสามารถนำมาใช้ประโยชน์ได้อย่างแน่นอน แมโคร (Macros) ก็สามารถช่วยได้มาก และการใช้ย่อหน้าความเห็นอย่างกว้างขวางเป็นแนวทางปฏิบัติที่ดีในทุกภาษา

แต่แนวทางการทำเอกสารในตัวนั้นได้รับการส่งเสริมโดยการใช้ภาษาระดับสูง และพบว่ามีประสิทธิภาพสูงสุดและมีความสมเหตุสมผลที่สุดเมื่อใช้ภาษาระดับสูงร่วมกับระบบออนไลน์ ไม่ว่าจะเป็นแบบแบตช์หรือแบบโต้ตอบ ดังที่ผมได้แย้งไว้ ภาษาและระบบดังกล่าวช่วยเหลือนักเขียนโปรแกรมในทางที่มีพลังอย่างยิ่ง ในเมื่อเครื่องจักรถูกสร้างขึ้นเพื่อมนุษย์ ไม่ใช่มนุษย์เพื่อเครื่องจักร การใช้งานพวกมันจึงสมเหตุสมผลในทุกมิติ ทั้งในเชิงเศรษฐศาสตร์และเชิงมนุษยธรรม