รูปแบบการเขียนโปรแกรม (Programming paradigms)
| English | ไทย |
|---|---|
| paradigm/ˈpærədaɪm/ | แนวความคิดในการเขียนโปรแกรม (paradigm) |
| low-level/ləʊ ˈlevl/ | low-level |
| imperative/ɪmˈperətɪv/ | imperative |
| declarative/dɪˈklærətɪv/ | declarative |
| functional/ˈfʌŋkʃənl/ | เชิงฟังก์ชัน |
| pure functions/pjʊə ˈfʌŋkʃnz/ | ฟังก์ชันบริสุทธิ์ |
| logic/ˈlɒdʒɪk/ | ตรรกะ |
โปรแกรมเดียวกัน เขียนด้วยสี่วิธี
- ขอข้อมูลลูกค้าทั้งหมดในสหราชอาณาจักร นักเขียนโปรแกรม C จะเขียนลูปวนผ่านอาร์เรย์ นักเขียน Haskell จะเขียน Filter นักเขียน Prolog จะกำหนดกฎแล้วตั้งคำถาม ผู้ใช้ SQL จะเขียน
SELECT * FROM Customer WHERE Country = 'UK' - เฉพาะข้อแรกเท่านั้นที่บอก วิธีการ ทำ ส่วนอีกสามข้อบอก สิ่งที่ต้องการ และปล่อยให้เครื่องจัดการ โดยเครื่องมีอิสระที่จะจัดลำดับงานใหม่ ใช้ดัชนี หรือรันบน eight cores
- ไม่มีสิ่งใดดีกว่ากันโดยทั่วไป สิ่งที่แตกต่างกันคือคำตัดสินใจที่ภาษาดึงไปจากคุณ และนี่แหละคือสิ่งที่ Paradigm คือ
- บทเรียนนี้เกี่ยวกับ Paradigms ที่หลักสูตรระบุ: Low-level, Imperative และ Declarative
การเขียนโปรแกรม Low-level
- Low-level programming ทำงาน ใกล้กับฮาร์ดแวร์ ในรูปแบบ Machine code หรือ Assembly language โดยมีเข้าถึง Register, ที่อยู่หน่วยความจำ และคำสั่งแต่ละตัวโดยตรง
- ข้อดี: ได้ ควบคุม สูงสุดและ ความเร็ว สูงสุด รวมถึงโค้ดที่มีขนาดเล็กที่สุด ซึ่งสำคัญเมื่อมีหน่วยความจำเพียงกิโลไบต์
- ข้อเสีย: เป็น เฉพาะสถาปัตยกรรม จึงต้องเขียนใหม่สำหรับโปรเซสเซอร์อื่น และเขียนได้ยากและดูแลรักษายาก
- ใช้ในพื้นที่ที่ต้องสั่งฮาร์ดแวร์อย่างแม่นยำ: Device drivers, Firmware, Embedded controllers และ Innermost loop ของ Real-time system
- ฝึกปฏิบัติ immediate, direct, indirect, indexed และ relative addressing ใน บทเรียนภาษาอะซัมบลี. การติดตามตัวอย่างแสดงให้เห็น почему operand เดียวกันสามารถสร้างผลลัพธ์ที่แตกต่างกันได้
ข้อใดถูกต้องเกี่ยวกับการเขียนโปรแกรมระดับต่ำ? เลือก ทุก ข้อที่ใช่
การควบคุมมาพร้อมกับความพยายาม: การเขียน Assembly ช้าและบำรุงรักษายาก จึงใช้เฉพาะในไดรเวอร์และเฟิร์มแวร์เท่านั้น
การเขียนโปรแกรม Imperative
- Imperative programming หรือที่เรียกว่า Procedural คือ ลำดับของคำสั่งที่เปลี่ยนสถานะของโปรแกรม: Assignment, Conditionals, Loops และการเรียก Procedure
- นักเขียนโปรแกรมระบุ วิธีการ คำนวณผลลัพธ์ทีละขั้นตอน ตัวแปรที่เก็บสถานะเป็นจุดสำคัญ
- เป็นสไตล์ของ Python, C, Java และ Pseudocode และเป็นสิ่งที่ทุกคนเกือบทุกคนเรียนรู้เป็นอันดับแรก

คำสั่งหนึ่งตามอีกคำสั่งหนึ่ง เปลี่ยนสิ่งที่ถูกจัดเก็บ
การเขียนแบบ Imperative (Procedural) ยึดตาม:
โค้ด Imperative ให้คำสั่งทีละขั้นตอน (การกำหนดค่า, ลูป, การเรียกใช้) เพื่อเปลี่ยนสถานะ
การเขียนโปรแกรม Declarative
- Declarative programming บอก สิ่งที่ต้องการคำนวณ ไม่ใช่ วิธีการ Runtime จะหาขั้นตอนเอง
- Functional programming สร้าง Pure functions ซึ่งไม่มี Side effects: อินพุตเท่าเดิมให้เอาต์พุตเท่าเดิมเสมอ และไม่มีอะไรภายนอกฟังก์ชันเปลี่ยนแปลง Haskell และ Lisp เป็นตัวอย่าง
- Logic programming บอกข้อเท็จจริงและกฎ และ Engine ตอบคำถามด้วยการอนุมาน Prolog เป็นตัวอย่าง
- SQL เป็นภาษา Declarative ที่ทุกคนเคยเจอ: Query บอกว่าต้องการ Row ไหน และ Database ตัดสินใจวิธีค้นหา
ห้องปฏิบัติการแนวคิดการเขียนโปรแกรม
เชื่อมโยงตัวอย่างเข้ากับแนวคิดการเขียนโปรแกรมที่แสดงออก
การเขียนแบบ Declarative หมายความว่าคุณระบุ:
โค้ด Declarative (Functional, Logic, SQL) ระบุเป้าหมาย; Runtime ตัดสินใจขั้นตอน
ฟังก์ชันบริสุทธิ์ (Functional programming):
Purity หมายความว่าไม่มี Side Effects และมีผลลัพธ์ที่แน่นอน ทำให้ Functional Code เข้าใจง่าย
Declarative Paradigms (Functional, Logic, SQL) ระบุว่า WHAT ต้องคำนวณและปล่อยให้ Runtime ตัดสินใจ HOW ในขณะที่ Imperative โค้ดระบุทุกขั้นตอน
SQL Query บอกว่าต้องการแถวไหน ไม่บอกวิธีสแกนตาราง — ตรงข้ามกับ Imperative โค้ดแบบทีละขั้นตอน
ฟังก์ชันบริสุทธิ์ให้เอาต์พุตเหมือนเดิมสำหรับอินพุตเดียวกันและไม่มีการ ____
นั่นคือสิ่งที่ทำให้ทดสอบแยกส่วน ได้运行แบบขนานปลอดภัย และมีผลเก็บ Cache ได้
ตัวอย่างเชิงปฏิบัติ: ระบุ Paradygm
FOR i ← 1 TO n : total ← total + A[i] : NEXT i— imperative: ลำดับคำสั่งที่เปลี่ยนสถานะที่เก็บไว้ในtotalSELECT Name FROM Customer WHERE Country = 'UK'— declarative: บอกว่าต้องการ Row ไหนและไม่บอกว่าค้นหาอย่างไรLDD 200 : ADD 201 : STO 202— low-level: คำสั่ง Assembly ที่เข้าถึงตำแหน่งหน่วยความจำโดยตรงparent(X, Y) :- father(X, Y).— declarative โดยเฉพาะ logic programming: กฎที่ Engine อนุมานคำตอบออกมา- ชื่อนาม Paradygm และ คุณสมบัติของโค้ดที่แสดงออกถึงมัน
จับคู่แต่ละ Fragment กับ Paradygm ของมัน
คำสั่งเปลี่ยนสถานะ, ข้อความว่าต้องการอะไร, คำสั่งเข้าถึงหน่วยความจำ, และกฎสำหรับการสันนิษฐาน
เปรียบเทียบกัน
| Paradygm | บอก | จุดแข็ง | การใช้ทั่วไป |
|---|---|---|---|
| low-level | คำสั่งที่แน่นอน | ควบคุม, ความเร็ว, ขนาด | Drivers, Firmware |
| imperative | วิธีการ, ทีละขั้น | ตรงไปตรงมาและเป็นที่ยอมรับ | การเขียนโปรแกรมทั่วไป |
| declarative | สิ่งที่ต้องการ | กระชับ, Runtime ทำการ Optimize | Queries, Rules, Data transformation |
- ภาษาสมัยใหม่ ผสม ทั้งสอง Python เป็น imperative แต่มีคุณสมบัติ functional; SQL อยู่ภายในโปรแกรมที่เขียนแบบ imperative Paradygmคือสไตล์ ไม่ใช่กำแพงกั้น
จับคู่แต่ละ Paradygmm กับแนวคิดหลัก
Imperative บอกHOW ทีละขั้นตอน; OO จำลองออบเจกต์; Functional ใช้ Pure Functions; Declarative ระบุเป้าหมาย
ความแตกต่างพื้นฐานระหว่าง Imperative และ Declarative Programming คืออะไร?
เพราะเวอร์ชัน Declarative ไม่ได้กำหนดHOW Runtime อาจเรียงลำดับงาน ใช้ Index หรือแบ่งเป็นแบบขนาน
ตัวอย่างเชิงปฏิบัติ: ทำไม Side effects ถึงสำคัญ
- Pure function ไม่มี side effects อธิบายประโยชน์หนึ่ง.
- เนื่องจากอินพุตเท่าเดิมให้เอาต์พุตเท่าเดิมเสมอและไม่มีอะไรภายนอกเปลี่ยน Pure function สามารถ ทดสอบแยกต่างหาก: ไม่ต้องตั้งค่า ไม่มีความ trạngซ่อนเร้นที่ต้องเตรียม
- ยังสามารถรันใน Parallel ได้อย่างปลอดภัย เพราะสอง Call ไม่รบกวนกัน และผลลัพธ์สามารถ Cache ได้
- ความแตกต่าง: Routine แบบ imperative ที่อัปเดต Global variable จะทำงานต่างกันขึ้นอยู่กับสิ่งที่รันมาก่อนหน้า นี่คือสาเหตุที่ทำให้ Bug แบบนี้หาได้ยาก
คะแนนที่หลุดหายไป
- Imperative บอก how; Declarative บอก what ความแตกต่างนี้คือคำตอบของคำถามส่วนใหญ่ในที่นี้
- ข้อเสียของ Low-level คือเป็น architecture-specific และดูแลรักษายาก ไม่ใช่เพราะ它是 "เก่า"
- Pure function ไม่มี side effects และให้เอาต์พุตเท่าเดิมสำหรับอินพุตเท่าเดิม ต้องมีทั้งสองส่วน
- SQL เป็น declarative เป็นตัวอย่างที่สอบมักใช้มากที่สุด ดังนั้นต้องจดจำได้
คุณเข้าใจแล้ว
- a paradigm คือสไตล์การจัดโครงสร้างโค้ด และภาษาสมัยใหม่ผสมหลายอย่าง
- low-level: Machine code หรือ Assembly เข้าถึงฮาร์ดแวร์โดยตรง ควบคุมและความเร็วสูงสุด แต่เฉพาะสถาปัตยกรรมและดูแลรักษายาก
- imperative: ลำดับคำสั่งที่เปลี่ยนสถานะ ระบุ how; สไตล์ของ Python, C และ Pseudocode
- declarative: บอก what ที่ต้องการและปล่อย how ให้ Runtime ทำ เช่น functional programming กับ pure functions, logic programming กับข้อเท็จจริงและกฎ และ SQL