หัดเขียนโปรแกรมยังไงให้เก่ง?

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

ก่อนอื่น ต้องทำความเข้าใจพื้นฐานก่อน ว่า

“การเขียนโปรแกรม”​ มันเป็นเรื่อง “Skill การสื่อสาร”

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

ปัญหาอันดับแรกๆ ที่ผมพบก็คือ “คิดเป็นขั้นตอนไม่เป็น”

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

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

ดังนั้นในการสื่อสาร เราจะมีปัจจัยตั้งต้นคือ “ชีท” และ “กลุ่มคน”​ และปลายทางที่เราต้องการคือ “ทุกคนในกลุ่ม ได้รับชีทที่ถ่ายเอกสารแล้ว” ถ้าจะสื่อสารเป็นกระบวนการแบบโปรแกรม หรือฟังก์ชั่นทางคณิตศาสตร์ ก็จะได้ลักษณะนี้

จำนวน = นับ(คนในกลุ่ม)
ชีทที่ถ่ายเอกสารแล้ว = ถ่ายเอกสาร(ชีท, จำนวน)
คนที่ได้รับชีท = แจกจ่าย(ชีทที่ถ่ายเอกสารแล้ว, คนในกลุ่ม)

เป็นต้น

ปัญหาอันดับต่อไปที่ผมพบก็คือ การให้ความสำคัญกับตัวภาษาโปรแกรมมากไปในตอนแรก (แต่น้อยไปในระยะหลังจากนั้น)

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

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

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

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

ตัวอย่างง่ายๆ ผมเชื่อว่าแทบทุกคนรู้จัก

printf("Hello, world\n");

(หรืออะไรก็ได้ที่เทียบเท่ากัน ซึ่งแตกต่างกันไปตามภาษา) ซึ่งมักจะได้เรียนกันในคลาสแรก ไม่ก็หนังสือบทแรก แต่จะมีกี่คนเชียวที่ “เล่น” กับมันต่อ เอาไปหัดสื่อสารมันต่อ ลองหาดูว่าจะประยุกต์หรือพลิกแพลงมันอย่างไรได้บ้าง เช่น จะลองให้แสดง

Name            Lastname        Sword
Byakuya         Kuchiki         Senbonsakura
Sousuke         Aizen           Kyokazuigetsu

โดยช่องว่างให้เว้นว่างทั้งหมด 2 Tab และให้ได้โดยใช้ printf เพียงตัวเดียว ทำได้หรือไม่ อย่างไร อะไรทำนองนี้

======================================

สรุปสั้นๆ การเขียนโปรแกรมก็เหมือนกับการสื่อสาร คิดว่าทำอย่างไรให้สื่อสารเก่ง ก็ทำแบบนั้นกับการเขียนโปรแกรม หลายคนอยากจะพูดภาษาอังกฤษเก่ง แต่เจอฝรั่งทีไรวิ่งหนีทุกที ให้พูดก็ไม่ยอมพูด แล้วมันจะเก่งได้อย่างไร ต่อให้วันๆ นั่งท่องไวยากรณ์ นั่งท่องศัพท์ ก็ไม่เคยมีประโยชน์ … พูดในฐานะคนที่พูดได้ 3 ภาษา ฟังออก 4 อ่านออก 6 ภาษา (แต่เป็นงูๆ ปลาๆ ไม่ค่อยแข็งแรงเท่าไหร่ซะ 3) นะครับ

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

สุดท้ายคือ ให้ “ลงมือทำ” เพราะความ “อยากได้” มันไม่เคยมีประโยชน์เลย ถ้าไม่ “ลงมือทำ”

======================================

เรื่องสุดท้าย … แต่ก่อนอื่นต้องขอเล่าเรื่องตัวเองให้ฟังสักหน่อย ผมมีวิธีการเรียนเขียนโปรแกรมอยู่อย่างหนึ่ง ซึ่งโดยส่วนตัวแล้วมันเวิร์กสำหรับผม คือ

หัดให้ “มือ” เขียนโค้ด อย่า copy & paste เด็ดขาด และอย่าใช้สมองคิดโค้ดโดยไม่จำเป็น

เวลาผมจะหัดเขียนโปรแกรมในภาษาใหม่ และหัดจากหนังสือ ไม่ว่าจะเป็นหนังสือใครเขียน (และแน่นอน ว่าผมลองทำแบบนี้กับหนังสือตัวเองด้วย) ผมจะ “อ่านเนื้อหาผ่านๆ” ก่อน 1 เที่ยว จากนั้น “พิมพ์” โค้ดเหล่านั้นเองด้วย “มือตัวเอง” ผมจะไม่เคย copy & paste โค้ดในช่วงของการเรียนรู้เลย เพราะว่าสิ่งที่สำคัญที่สุดคือ มือผมต้องโค้ดเป็น

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

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

ซึ่งนี่คืออีกปัญหาที่ผมพบ ซึ่งเป็นปัญหา “ใหญ่ที่สุด” คือ ผู้ฝึกเขียนโปรแกรม ต้องการได้ผลลัพธ์สำเร็จรูปเร็วเกินไป ฉาบฉวยเกินไป ต้องการโค้ดที่เอาไป copy & paste ได้ กด compile & run เห็นผลลัพธ์ แล้วคนขยันหน่อย ก็อาจจะกลับมานั่งอ่านโค้ดบ้าง นอกนั้นก็ปล่อยๆ มันไป เพราะได้ผลแล้ว

ปัญหาที่ว่าน้ีก็คือ “โค้ดไม่เคยผ่านมือ” และ “ไม่ได้เป็นคนเริ่มเอง” (แต่เริ่มจากโปรเจคที่เสร็จแล้ว ที่คนอื่นเริ่มไว้ให้แล้ว) ซึ่งทำให้เวลาต้องทำงานจริงๆ จะเริ่มต้นอะไรเองไม่เป็นเลย และโค้ดเองไม่เป็นเลย มือมันจะไม่ขยับ และต้องไปเปลืองแรงสมองคิดโดยใช่เหตุถึงเรื่องโค้ด แล้วหลายคนก็จะ Blank .. ตายตรงนี้

ผมมีข้อสังเกต ว่าถึงระบบการศึกษาบ้านเรามันจะไม่ได้แย่ลงกว่าเดิมเท่าไหร่ แต่ทำไมคนเดี๋ยวนี้เขียนโปรแกรมแย่ลงกว่าเมื่อก่อนมาก ก็เพราะมันเริ่มต้น “ง่ายเกินไป” และ “ฉาบฉวยเกินไป” มีโค้ดอยู่แล้ว copy & paste ง่าย แค่ Ctrl+C, Ctrl+V ก็จบแล้ว หรือไม่ก็ download งานที่เสร็จแล้วมา unzip แล้วใช้งานได้เลย ดังนั้นโค้ดจะไม่ผ่านมือเลย ซึ่งนี่คือเรื่องที่หลายคนอาจมองว่ามัน “เล็กน้อย” แต่จริงๆ แล้วนี่คือเรื่องที่ “ใหญ่ที่สุด” เรื่องหนึ่ง

สมัยผมหัดเขียน C++ 98 (ที่เป็น Standard แรกที่มี STL) ผมซื้อหนังสือ The C++ Standard Template Library ของ Nicolai Josuttis มานั่งอ่านผ่านๆ ทั้งเล่มก่อน 1 เที่ยว และ “นั่งลอก” โค้ดทุกบรรทัดด้วยมือตัวเอง ทั้งเล่ม จากนั้นค่อยพยายามศึกษารายละเอียดอีกครั้งในเบื้องลึก

ซึ่งนี่เป็นวิธีเดียวกับที่ผมศึกษา Perl, Ruby, Objective-C, Mathametica, Haskell, OCaml, Scheme และภาษาอื่นๆ ที่ผมเขียนเป็น และเขียนพอเป็น

และนี่แหละ เป็นสาเหตุที่ผม “ไม่อยากให้โค้ด” สำหรับโปรแกรมจากหนังสือคู่มือเขียน iPhone App ของผม ซึ่งพิมพ์โดยสำนักพิมพ์ Provision

สรุปสั้นๆ: อยากเขียนโปรแกรมเก่ง ต้องหัด “เขียน” โปรแกรมครับ อย่าหัดแต่รันโปรแกรมที่คนอื่นเขียนแล้ว

======================================

หวังว่าคงจะเป็นประโยชน์บ้าง …​ จริงๆ แล้วเนื้อหาบทความนี้ คัดมาจาก “บทแรก” ของหนังสือเล่มใหม่ที่ผมกำลังเขียนอยู่ (ยังไม่มีชื่ออย่างเป็นทางการ แต่ประมาณ “คิดและโค้ด ผ่านภาษา Objective-C”) โดยดัดแปลงให้เหมาะกับการเป็นบทความบนเว็บ

รออ่านนะครับ ผมหวังว่าจะเป็นหนังสือที่ดี(นะ)