ผมเรียนรู้อะไรจากการเขียนโปรแกรมใช้เอง (4) - abstraction


พลังของการคิดเชิงนามธรรม

ตอนจบทำงานใหม่ ๆ 8088 กำลังเป็นที่กล่าวขานในต่างประเทศ แต่บ้านเรายังเป็นวัตถุมงคลที่หาดูยากอยู่

คนยุคนี้อาจงง ว่า 8088 คืออะไร

8088 คือพี่ใหญ่ ก่อนจะมีน้อง ๆ ตามมาเป็นพรวน คือ 8086, 80286, 80386, 80486, Pentium, ฯลฯ

ความเร็วของ 8088 น่าจะประมาณ 1 ในพัน ของความเร็ว PC ตอนนี้ 

สมัยนั้นผมเปิดวารสาร เห็นรูปภาพสามมิติของการทำ response surface optimization ผมก็คิดในใจว่า โห เท่ห์จัง ! ต้องทำมั่ง !

ตอนนั้นผมก็เลยหัดใช้เครื่องคิดเลข casio-4000 มาทำ multivariable regression แม้ไม่สะดวก แต่ก็ทำจนได้ และทำให้ผมเริ่มเห็นขีดจำกัดของการไม่ทำ abstraction...(ผมต้องใช้ตัวแปรชื่อ a-z เท่านั้น ไม่มี array ซึ่ง array ก็คือ variable abstraction ในกรณีนี้)

ต่อมา ไปเรียนต่อโท งานอดิเรกของผมก็คือเขียนโปรแกรมยาวที่สุดในชีวิต ยาวเกือบสองพันบรรทัด เพื่อทำ multivariable regression เพื่อนำมาใช้วิเคราะห์ข้อมูล thesis โดยตั้งเป้าว่า จะให้โปรแกรมเลือก empirical model อัตโนมัติจาก built-in library ของ model ที่ผมใส่ไว้

ตอนนั้นผมใช้ PC-DOS แบบ boot และ run บน floopy disk ครับ ไม่มี hard disk และหน่วยความจำของ DOS ยังมีกำแพง 64K อยู่เลย คือถ้าขนาดโปรแกรมเกิน 6 หมื่นไบท์ ก็จะแฮงค์

ผลคือ เขียนไปได้ไม่เท่าไหร่ โปรแกรมก็ชนกำแพง 64K  ทำให้โปรแกรมรองรับ model ได้ไม่มาก

ผมจะทำอย่างไรดี ?

ขั้นแรก ผมใช้วิธี รื้อ-เขียนใหม่-รื้อ-เขียนใหม่ นับครั้งไม่ถูก ไม่เหนื่อยครับ แต่มันส์

อือม์..ผมลืมความรู้สึกตอนนั้นหมดแล้วละ... 

ก็ช่วยได้ ทำให้โปรแกรมกระชับขึ้นเรื่อย ๆ เติม model ได้มากขึ้น ๆ ๆ ผมเรียนรู้ทักษะการ debug อย่างเข้มข้น ก็ตอนนั้นแหละ

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

แต่เมื่อ model มากขึ้น ผมก็เริ่มรู้สึกว่า เอ๊ะ ผมหลงทางแล้ว เพราะผมต้องตาม synchronize code หลายแห่งพร้อม ๆ กัน คือต้องเขียนโค้ดหน้าตาคล้าย ๆ กันหลายรอบ ซึ่งอยู่ห่างกันมากในโปรแกรม และแยก module ก็ไม่ไหว เพราะไม่ได้ออกแบบให้ modular ไว้ก่อน ทำให้พลาดได้บ่อย

ผมได้เรียนรู้จากกรณีนี้ว่า เมื่อไหร่มนุษย์ต้องคีย์ข้อมูลซ้ำ ความผิดพลาด จะต้องเกิดขึ้นเสมอ ต่อให้ระวังขนาดไหนก็ตาม

ผมจะแก้ปัญหาได้อย่างไร ?

ตอนหลัง ผมมาลงเอยด้วยการเขียนโปรแกรมให้ทำหน้าที่คล้าย ๆ compiler เสียเอง โดยแยก mathematical model ออกไปอยู่นอกโปรแกรม แล้วให้โปรแกรมอ่าน model มาตีความ คล้าย ๆ กับที่ Windows ทำงานด้วยการ setting ค่าระบบเก็บใน text file ภายนอก แล้วอ่านมาตีความแล้วแสดงหน้าตาที่ผู้ใช้ตั้งไว้

แก้ได้สำเร็จ คราวนี้ผมไม่ต้องห่วงเรื่อง synchronize code อีกต่อไป 

ปัจจุบัน เป็นที่รู้จักกันดีว่า มีรูปแบบ 4 แบบของแนวคิดการออกแบบโปรแกรม

  • Program as program (โปรแกรมที่แสดงตัวว่าเป็นโปรแกรม แบบนี้ตรงไปตรงมาครับ)
  • Program as data (โปรแกรมที่แปลงโฉมให้เห็นเป็นข้อมูล เช่น การเขียนโปรแกรมแบบ genetic programming ซึ่งใช้วิธีหยิบชิ้นส่วนในคลังข้อมูล มาประกอบกันเป็นโปรแกรม แล้วลองรันใน sandbox เพื่อประเมินสมรรถนะ แล้วเปิดโอกาสให้โปรแกรมวิวัฒนาการไปเอง)
  • Data as program (ไวรัสในแฟ้มแนบ; configuration file ในกรณีนี้;  compiler; pre-compiler, ฯลฯ)
  • Data as Data (ตรงไปตรงมาครับ)

แนวคิด data as program (อ่าน data มา แล้วใช้ขับเคลื่อนให้ทำงานเสมือนหนึ่งเป็นโปรแกรม) เป็นแนวคิดที่ abstract (นามธรรม) แม้จะเสียเวลากว่ามากในการเขียน แต่มีข้อดีคือ ยืดหยุ่น เพราะผมสามารถปรับแต่ง built-in library ได้ง่ายโดยไม่ต้อง compile โปรแกรมใหม่

ผมตีพิมพ์งานวิจัยชิ้นแรก ๆ ในชีวิต ก็ได้ใช้โปรแกรมนี้แหละครับ มาวิเคราะห์ข้อมูล

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

จนตอนนี้ ชักติดนิสัย เวลาต้องคำนวณแบบ intensive ใช้โปรแกรมคนอื่นเขียนแล้วอึดอัด ต้องนับศูนย์ใหม่ ค่อยสาแก่ใจ 

(แต่งานประเภทอื่นที่ไม่ใช่การคำนวณเข้มข้น ผมก็ใช้โปรแกรมที่คนอื่นเขียนล้วน ๆ ไม่เคยมีความคิดจะเขียนเองเลยแม้แต่น้อย) 

สิ่งที่ผมได้เรียนรู้จากการเขียนโปรแกรมนี้ก็คือ abstraction คือหัวใจของการเขียนโปรแกรมที่ยืดหยุ่น

ยกตัวอย่างง่าย ๆ กรณีของ multivariable regression หากใช้วิธีแบบที่ผมเขียนในเครื่องคิดเลข casio โปรแกรมรับมือได้กับ model เดียว

แต่เมื่อมองแบบ abstract การหาค่า regression parameters สามารถอธิบายได้ด้วย vector notations เพียงไม่กี่บรรทัด ครอบคลุมความเป็นไปได้ของโปรแกรมนับไม่ถ้วน ซึ่งผมใช้เป็นแก่นโครงของโปรแกรมดังกล่าว

หลายปีให้หลัง แม้ในยุคที่ผมใช้ SQL เป็นหลัก ผมก็ยังพบว่า abstraction เป็นยาดำที่ทำให้งานต่าง ๆ ง่ายขึ้นมหาศาล

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

แต่ถ้าใช้เป็น จะทำให้เรื่องซับซ้อน กลายเป็นเรื่องเรียบง่ายสามัญ และมีสมรรถนะสูง

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

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

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

แต่ปัญหาที่แท้จริง กลับอยู่ลึกกว่านั้นมาก

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

แต่ก็เป็นประเด็นที่แปลก เพราะคนอื่นไม่ได้มองว่านี่เป็นปัญหา ทั้งที่เมื่อใช้งานจริง จะเจอปัญหาอย่างนี้ !

 

คำสำคัญ (Tags): #programming
หมายเลขบันทึก: 93907เขียนเมื่อ 2 พฤษภาคม 2007 17:08 น. ()แก้ไขเมื่อ 10 มิถุนายน 2012 15:36 น. ()สัญญาอนุญาต: จำนวนที่อ่านจำนวนที่อ่าน:


ความเห็น (0)

ไม่มีความเห็น

พบปัญหาการใช้งานกรุณาแจ้ง LINE ID @gotoknow
ClassStart
ระบบจัดการการเรียนการสอนผ่านอินเทอร์เน็ต
ทั้งเว็บทั้งแอปใช้งานฟรี
ClassStart Books
โครงการหนังสือจากคลาสสตาร์ท