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

ลำดับชั้นของภาษา: Python อยู่ตรงไหน

ภาษาโปรแกรมสามารถแบ่งออกเป็นสามประเภทใหญ่ๆ ตามความใกล้ชิดกับฮาร์ดแวร์

ภาษาระดับสูง (High-level languages) อยู่ห่างจากซิลิคอนมากที่สุด Python จัดอยู่ในกลุ่มนี้ เช่นเดียวกับ Java และ JavaScript ภาษาเหล่านี้ใช้ไวยากรณ์ที่คล้ายกับภาษาคน คุณเขียน user_count = 5 หรือ print("Hello") แทนที่จะต้องไปวุ่นวายกับที่อยู่หน่วยความจำ (memory addresses) และคำสั่งไบนารี เนื่องจากภาษาเหล่านี้ช่วยลดความซับซ้อน (abstract away) ของรายละเอียดเกี่ยวกับ CPU, การจัดการหน่วยความจำ และความแตกต่างของชิปเซ็ต ทำให้โค้ดระดับสูงชุดเดียวกันมักจะสามารถรันบน Mac, Windows PC หรือ Linux server ได้โดยแทบไม่ต้องแก้ไขอะไรเลย

ความสามารถในการพกพา (portability) นี้มีสิ่งที่ต้องแลกมา ภาษาระดับสูงจำเป็นต้องมีตัวแปลภาษา พวกมันไม่สามารถรันบนโปรเซสเซอร์ได้โดยตรง คุณต้องมีไม่ว่าจะเป็นคอมไพเลอร์ (compiler) หรืออินเทอร์พรีเตอร์ (interpreter) เพื่อเชื่อมช่องว่างระหว่างโค้ดที่อ่านง่ายของคุณกับสัญญาณไฟฟ้าของเครื่องจักร ข้อดีคือความเร็วในการพัฒนา คุณยอมเสียการควบคุมฮาร์ดแวร์โดยตรงเพื่อให้สามารถเขียนโปรแกรมที่มีประโยชน์ได้ตั้งแต่วันแรก

ภาษาระดับต่ำ (Low-level languages) อยู่ในขั้วตรงข้าม สิ่งเหล่านี้คือภาษาเครื่อง (machine code) โดยพื้นฐาน ซึ่งเป็นลำดับของเลขหนึ่งและศูนย์ที่โปรเซสเซอร์เข้าใจได้โดยตรง การเขียนภาษาเครื่องหมายถึงการต้องคิดเหมือนกับตัวชิปเอง คุณต้องตัดสินใจอย่างชัดเจนว่าที่อยู่หน่วยความจำใดจะถูกเข้าถึง และรีจิสเตอร์ (register) ของ CPU ตัวไหนจะเก็บค่าใดค่าหนึ่ง ฮาร์ดแวร์จะตอบสนองทันทีโดยไม่มีภาระจากการแปลภาษา (translation overhead)

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

ภาษาแอสเซมบลี (Assembly languages) อยู่ในพื้นที่ตรงกลางที่แคบกว่า พวกมันแทนที่คำสั่งไบนารีด้วยสัญลักษณ์สั้นๆ ที่มนุษย์อ่านออกซึ่งเรียกว่า mnemonic แทนที่จะเป็นชุดของเลขหนึ่งและศูนย์ คุณอาจเขียน MOV เพื่อย้ายข้อมูล หรือ ADD เพื่อทำการบวก สัญลักษณ์เหล่านี้จำได้ง่ายกว่าไบนารีดิบๆ แต่พวกมันยังคงผูกติดอย่างแน่นหนากับสถาปัตยกรรมของโปรเซสเซอร์เฉพาะรุ่น โปรแกรมแอสเซมบลีที่เขียนสำหรับชิป Intel x86 จะไม่สามารถรันบนโปรเซสเซอร์ ARM ได้

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

โค้ดกลายเป็นคำสั่งได้อย่างไร

ทุกโปรแกรมจะต้องกลายเป็นคำสั่งเครื่องในท้ายที่สุด เส้นทางจากซอร์สโค้ด (source code) ไปสู่แอปพลิเคชันที่ทำงานได้นั้นใช้หนึ่งในสองกลยุทธ์นี้

คอมไพเลอร์ (compiler) จะแปลโค้ดทั้งหมดของคุณในการทำงานเพียงรอบเดียว หากคุณส่งไฟล์ที่มีหนึ่งร้อยบรรทัดให้มัน มันจะอ่านและวิเคราะห์ทั้งหนึ่งร้อยบรรทัดก่อนที่จะพยายามรันอะไรก็ตาม มันจะสแกนหาข้อผิดพลาดทางไวยากรณ์ (syntax errors) ทั่วทั้งโปรแกรม หากพบคำที่พิมพ์ผิดในบรรทัดที่ห้าสิบ? คอมไพเลอร์จะหยุด รายงานปัญหา และปฏิเสธที่จะสร้างโปรแกรมที่รันได้จนกว่าคุณจะแก้ไขมัน

ภาษาอย่าง C และ C++ ใช้วิธีนี้ ผลลัพธ์ที่ได้มักจะเป็นไฟล์ executable ที่ทำงานได้ด้วยตัวเองและได้รับการปรับแต่งมาเพื่อความเร็วสูงสุด เนื่องจากคอมไพเลอร์ตรวจสอบโค้ดทั้งหมดล่วงหน้า มันจึงสามารถตรวจพบข้อผิดพลาดได้ทั้งกลุ่มก่อนที่โปรแกรมจะเริ่มทำงาน สิ่งที่ต้องแลกคือความไม่คล่องตัว วงจรการแก้ไข-คอมไพล์-รัน (edit-compile-run) นั้นใช้เวลา หากคุณเปลี่ยนโค้ดเพียงบรรทัดเดียว คุณอาจต้องรอให้โปรเจกต์ทั้งหมดถูกสร้างขึ้นใหม่

อินเทอร์พรีเตอร์ (interpreter) ใช้แนวทางที่แตกต่างกันโดยสิ้นเชิง มันจะอ่านโค้ดของคุณทีละบรรทัด แปลและดำเนินการตามแต่ละคำสั่งในขณะที่ทำงานไป มันไม่ต้องรอให้ไฟล์ทั้งหมดผ่านการตรวจสอบ เพียงแค่พิมพ์คำสั่งลงใน Python REPL กด Enter แล้วอินเทอร์พรีเตอร์จะประมวลผลบรรทัดนั้น แปลงเป็นคำสั่ง และรันทันที

สิ่งนี้เปลี่ยนลักษณะของการดีบั๊ก (debugging) เมื่อใช้อินเทอร์พรีเตอร์ (interpreter) ข้อผิดพลาดจะปรากฏขึ้นเมื่ออินเทอร์พรีเตอร์ทำงานมาถึงบรรทัดที่มีปัญหา ไม่ใช่ก่อนหน้านั้น โปรแกรมของคุณอาจทำงานได้อย่างสมบูรณ์แบบผ่านไปแปดสิบบรรทัด แล้วจึงเกิดการค้าง (crash) ในบรรทัดที่แปดสิบเอ็ด ความฉับไวนี้ทำให้อินเทอร์พรีเตอร์เป็นมิตรต่อการเรียนรู้มากขึ้น คุณสามารถทดลอง ดูผลลัพธ์ และปรับเปลี่ยนได้แบบเรียลไทม์ CPython ซึ่งเป็นตัวติดตั้งมาตรฐานของ Python แท้จริงแล้วใช้โมเดลแบบไฮบริด โดยจะคอมไพล์ซอร์สโค้ดของคุณเป็นไบต์โค้ด (bytecode) จากนั้นจึงรันไบต์โค้ดนั้นผ่านเวอร์ชวลแมชชีน (virtual machine) ผลลัพธ์ที่ได้จะให้ความรู้สึกเหมือนการทำงานแบบโต้ตอบและทีละบรรทัด แม้ว่าจะมีขั้นตอนการแปลคำสั่งซ่อนอยู่เบื้องหลังก็ตาม

ทำไม Python ถึงถูกเรียกว่าเป็นภาษาสคริปต์ (Scripting Language)

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

เส้นแบ่งระหว่างภาษาสคริปต์และภาษาโปรแกรมเอนกประสงค์ (general-purpose programming languages) นั้นเลือนลางลงอย่างมาก ปัจจุบัน Python ขับเคลื่อนแอปพลิเคชันเว็บขนาดใหญ่, ไพป์ไลน์ด้านวิทยาศาสตร์ข้อมูล (data science pipelines) และระบบแมชชีนเลิร์นนิง (machine learning systems) ถึงอย่างนั้น แนวคิดหลักก็ยังคงเดิม คือคุณมุ่งเน้นไปที่การแก้ปัญหามากกว่าการจัดการระบบการ build อินเทอร์พรีเตอร์พร้อมที่จะรันคำสั่งของคุณทันทีที่คุณต้องการ

การสร้างรากฐานที่มั่นคง

ความแตกต่างเหล่านี้ไม่ใช่เพียงความรู้เชิงวิชาการที่ดูเหมือนไม่สำคัญ แต่มันอธิบายพฤติกรรมที่คุณจะได้พบเจอในช่วงสัปดาห์แรกของการเขียน Python เมื่อ Python แจ้งข้อผิดพลาด SyntaxError ระหว่างการทำงาน ตอนนี้คุณจะเข้าใจแล้วว่าอินเทอร์พรีเตอร์ทำงานมาถึงบรรทัดที่มันไม่สามารถแปลได้ เมื่อคุณอ่านเจอว่า Python ทำงานช้ากว่าภาษา C ในบางงาน คุณจะเข้าใจถึงค่าใช้จ่ายส่วนเกิน (overhead) ของการแปลคำสั่งและการทำ abstraction ระดับสูง และเมื่อคุณสังเกตเห็นไฟล์ .pyc ปรากฏขึ้นข้างๆ สคริปต์ของคุณ คุณจะตระหนักว่า Python กำลังทำแคช (caching) ไบต์โค้ดที่คอมไพล์แล้ว เพื่อที่มันจะได้ไม่ต้องแปลไฟล์ข้อความของคุณใหม่ในทุกๆ ครั้งที่รัน

การรู้ว่า Python อยู่ตรงไหนในลำดับชั้นของภาษา ยังช่วยให้คุณเลือกเครื่องมือที่เหมาะสมได้ในภายหลัง หากคุณจำเป็นต้องเขียนไดรเวอร์อุปกรณ์ (device driver) ที่ทุกรอบการทำงานของ CPU (CPU cycle) มีความสำคัญ คุณอาจจะเลือกใช้ภาษา C หรือ assembly แต่ถ้าคุณต้องการประมวลผลไฟล์ CSV หรือสร้าง web API ให้เสร็จภายในบ่ายวันเดียว อินเทอร์พรีเตอร์และไวยากรณ์ที่อ่านง่ายของ Python ถูกสร้างมาเพื่อสิ่งนั้นโดยเฉพาะ

บทสรุปที่สำคัญ

พลังของ Python มาจากตำแหน่งที่มันอยู่ มันทำงานอยู่สูงเหนือฮาร์ดแวร์ โดยถูกแปลผ่านอินเทอร์พรีเตอร์ที่ให้ความสำคัญกับความเร็วในการเขียนโปรแกรมของผู้พัฒนามากกว่าความเร็วในการประมวลผลของเครื่อง คุณสามารถเรียนรู้ไวยากรณ์ได้โดยไม่จำเป็นต้องรู้พื้นฐานเหล่านี้ แต่คุณจะไม่สามารถดีบั๊กได้อย่างชาญฉลาดหรือปรับแต่ง (optimize) ได้อย่างเป็นสัญชาตญาณ จนกว่าคุณจะเข้าใจกลไกที่อยู่เบื้องล่าง เริ่มต้นด้วยพื้นฐานเหล่านี้ และเมื่อคุณเขียนโปรแกรมจริงตัวแรก คุณจะไม่ใช่แค่การพิมพ์คำสั่งลงไป แต่คุณจะรู้แน่ชัดว่าคำสั่งเหล่านั้นส่งไปถึงเครื่องได้อย่างไร