ไวยากรณ์และสัญลักษณ์ของภาษา APL
สรุปใจความสำคัญ
- APL เป็นภาษาโปรแกรมเชิงสัญลักษณ์ที่ใช้สัญลักษณ์ทางคณิตศาสตร์แทนคำสั่งพื้นฐาน
- ประมวลผลคำสั่งจากขวาไปซ้าย (Right-to-Left) ซึ่งแตกต่างจากภาษาโปรแกรมส่วนใหญ่
- ใช้ระบบฟังก์ชันโมนาดิก (รับ 1 อาร์กิวเมนต์) และไดแอดิก (รับ 2 อาร์กิวเมนต์) โดยสัญลักษณ์ตัวเดียวอาจทำหน้าที่ได้ทั้งสองแบบ
- ตัวดำเนินการ (Operator) ใน APL หมายถึงสิ่งที่ใช้ปรับเปลี่ยนการทำงานของฟังก์ชัน ไม่ใช่สิ่งที่กระทำกับข้อมูลโดยตรง
ภาษา APL (A Programming Language) มีความโดดเด่นและแตกต่างจากภาษาโปรแกรมส่วนใหญ่ เนื่องจากเป็นภาษาเชิงสัญลักษณ์ (Symbolic Language) แทนที่จะเป็นภาษาเชิงคำ (Lexical Language) โดยคำสั่งพื้นฐานหรือ Primitives ของภาษาจะถูกแทนที่ด้วยสัญลักษณ์พิเศษแทนการใช้คำศัพท์ ซึ่งสัญลักษณ์เหล่านี้ถูกออกแบบมาโดยมีพื้นฐานมาจากสัญลักษณ์ทางคณิตศาสตร์เพื่อใช้ในการอธิบายอัลกอริทึม
แม้ว่านักเขียนโปรแกรม APL มักจะตั้งชื่อเรียกฟังก์ชันและตัวดำเนินการอย่างไม่เป็นทางการเมื่อมีการสนทนา (เช่น เรียก ×/ ว่า "product") แต่ในตัวภาษาเอง ฟังก์ชันและตัวดำเนินการหลักจะถูกระบุด้วยสัญลักษณ์ที่ไม่ใช่ตัวอักษรทั้งหมด
ฟังก์ชันโมนาดิกและไดแอดิก (Monadic and Dyadic Functions)
สัญลักษณ์ส่วนใหญ่ใน APL จะทำหน้าที่เป็นฟังก์ชันหรือตัวดำเนินการ โดยการตีความจะขึ้นอยู่กับจำนวนอาร์กิวเมนต์ที่ได้รับ:
- ฟังก์ชันโมนาดิก (Monadic Function): คือฟังก์ชันที่รับอาร์กิวเมนต์เพียงตัวเดียว ซึ่งจะได้มาจากผลลัพธ์ของการประเมินค่าทุกอย่างที่อยู่ทางด้านขวาของสัญลักษณ์นั้น (โดยมีการใช้เครื่องหมายวงเล็บเพื่อควบคุมลำดับการทำงานตามปกติ)
- ฟังก์ชันไดแอดิก (Dyadic Function): คือฟังก์ชันที่รับอาร์กิวเมนต์สองตัว โดยอาร์กิวเมนต์ตัวแรกจะมาจากข้อมูลที่อยู่ทางด้านซ้ายของสัญลักษณ์ และอาร์กิวเมนต์ตัวที่สองมาจากผลลัพธ์ทางด้านขวา
สัญลักษณ์หนึ่งตัวอาจทำหน้าที่เป็นทั้งฟังก์ชันโมนาดิกและไดแอดิก ขึ้นอยู่กับบริบทการใช้งาน ตัวอย่างเช่น สัญลักษณ์ ⌊ (Floor) หากใช้แบบโมนาดิก ⌊3.2 จะได้ผลลัพธ์เป็น 3 (จำนวนเต็มที่มากที่สุดที่ไม่เกินค่าที่กำหนด) แต่หากใช้แบบไดแอดิก 3⌊2 จะได้ผลลัพธ์เป็น 2 (ค่าที่น้อยกว่าระหว่างสองจำนวน)
ฟังก์ชันและตัวดำเนินการ (Functions and Operators)
ในภาษา APL คำว่า "ตัวดำเนินการ" (Operator) ถูกใช้ในความหมายตามแนวคิดของ Heaviside ซึ่งหมายถึงสิ่งที่ทำหน้าที่ปรับเปลี่ยนหรือควบคุมฟังก์ชัน (Moderator of a function) ซึ่งแตกต่างจากภาษาโปรแกรมอื่นที่มักใช้คำว่าตัวดำเนินการเพื่อหมายถึงสิ่งที่กระทำกับข้อมูลโดยตรง
ตัวดำเนินการ Reduce (Slash Operator)
ตัวดำเนินการ Reduce ซึ่งแทนด้วยสัญลักษณ์สแลช / จะทำหน้าที่ลดรูปอาเรย์ตามแกนหนึ่งโดยการแทรกฟังก์ชันที่กำหนดไว้ด้านหน้า ตัวอย่างเช่น ×/ 2 3 4 จะเป็นการนำฟังก์ชันคูณ × มาใช้ร่วมกับตัวดำเนินการ Reduce เพื่อหาผลคูณของสมาชิกทุกตัวในเวกเตอร์ {2, 3, 4} ซึ่งจะได้ผลลัพธ์เป็นค่าสเกลาร์ (Scalar) เพียงค่าเดียว
การใช้ค่าบูลีนในการขยายและทำซ้ำ
สัญลักษณ์บางตัวสามารถให้ผลลัพธ์ที่ตรงกันข้ามกันอย่างสิ้นเชิงเมื่อใช้ค่าบูลีน (0 และ 1) เป็นอาร์กิวเมนต์ทางด้านซ้าย:
- การขยาย (Expand
\): หากใช้ค่าบูลีน 0 ในตำแหน่งอาร์กิวเมนต์ซ้าย จะทำให้เกิดการแทรกค่า 0 ลงในเวกเตอร์ - การทำซ้ำ (Replicate
/): ในทางกลับกัน หากใช้ค่าบูลีน 0 ในตำแหน่งอาร์กิวเมนต์ซ้าย จะทำให้สมาชิกในตำแหน่งนั้นถูกลบออกไปจากเวกเตอร์
นอกจากนี้ สัญลักษณ์ของ APL ยังสามารถทำงานกับข้อมูลประเภทอื่นนอกเหนือจากตัวเลขได้ เช่น เวกเตอร์ของข้อความ (Character Strings)
กฎเกณฑ์ทางไวยากรณ์ (Syntax Rules)
ลำดับการประเมินค่า (Precedence)
ลำดับความสำคัญของฟังก์ชันหรือตัวดำเนินการใน APL ถูกกำหนดโดยตำแหน่งอย่างเคร่งครัด โดยจะ ประเมินค่าจากขวาไปซ้าย (Right-to-Left Evaluation) ซึ่งแตกต่างจากภาษาโปรแกรมทั่วไปที่ใช้ลำดับความสำคัญของตัวดำเนินการ (Operator Precedence) เช่น ในภาษาอื่นการคูณจะทำก่อนการบวก แต่ใน APL การคูณ × และการบวก + มีน้ำหนักเท่ากัน และจะถูกประมวลผลตามลำดับจากขวาไปซ้าย
ขอบเขตของฟังก์ชัน (Scope)
APL ใช้แนวคิดเรื่อง "ขอบเขต" (Scope) เพื่อกำหนดอาร์กิวเมนต์ของฟังก์ชัน:
- ขอบเขตขวาแบบยาว (Long Right Scope): ฟังก์ชันจะรับทุกอย่างที่อยู่ทางด้านขวาเป็นอาร์กิวเมนต์
- ขอบเขตซ้ายแบบสั้น (Short Left Scope): ฟังก์ชันไดแอดิกจะรับข้อมูลชิ้นแรกที่อยู่ทางด้านซ้ายเป็นอาร์กิวเมนต์
ตัวอย่างเช่น ในการคำนวณที่ไม่มีวงเล็บ APL จะเริ่มประมวลผลจากขวาสุดก่อน แล้วนำผลลัพธ์นั้นไปเป็นอาร์กิวเมนต์ขวาให้กับฟังก์ชันที่อยู่ถัดมาทางซ้ายมือ ทำเช่นนี้ไปเรื่อยๆ จนถึงซ้ายสุด
ตัวดำเนินการระดับสูง (Advanced Operators)
- ตัวดำเนินการ Over-each (
¨): ใช้เพื่อสั่งให้ฟังก์ชันทำงานกับสมาชิกแต่ละตัวในอาเรย์แยกกัน เช่น⍳¨ 3 3จะสร้างเวกเตอร์ซ้อน (Nested Vector) ที่ประกอบด้วย{1 2 3}และ{1 2 3} - ตัวดำเนินการ Compose (
∘): ใช้สำหรับเชื่อมฟังก์ชันสองฟังก์ชันเข้าด้วยกัน เพื่อให้ผลลัพธ์ของฟังก์ชันหนึ่งกลายเป็นอาร์กิวเมนต์ของอีกฟังก์ชันหนึ่ง - ตัวดำเนินการ Commute (
⍨): ใช้เพื่อสลับตำแหน่งอาร์กิวเมนต์ของฟังก์ชันไดแอดิก
การผสมผสานตัวดำเนินการเหล่านี้ช่วยให้ APL สามารถสร้างคำสั่งที่สั้นและทรงพลัง เช่น การสร้างเมทริกซ์เอกลักษณ์ (Identity Matrix) ซึ่งมีประโยชน์อย่างยิ่งในการแก้สมการเชิงเส้นและการวิเคราะห์การถดถอยพหุคูณ
คำถามที่พบบ่อย
ภาษา APL แตกต่างจากภาษาโปรแกรมทั่วไปอย่างไร?
ความแตกต่างหลักคือ APL ใช้สัญลักษณ์พิเศษแทนคำสั่ง (Symbolic) แทนที่จะใช้คำศัพท์ (Lexical) และมีการประมวลผลจากขวาไปซ้าย ซึ่งทำให้โค้ดมีความกระชับมาก
ฟังก์ชันโมนาดิกและไดแอดิกคืออะไร?
ฟังก์ชันโมนาดิกคือฟังก์ชันที่รับอาร์กิวเมนต์เพียงตัวเดียว (ทางด้านขวา) ส่วนฟังก์ชันไดแอดิกคือรับอาร์กิวเมนต์สองตัว (หนึ่งตัวทางซ้ายและหนึ่งตัวทางขวา)
ลำดับการทำงานของ APL เป็นอย่างไร?
APL ประเมินค่าจากขวาไปซ้ายอย่างเคร่งครัด โดยไม่มีลำดับความสำคัญของตัวดำเนินการ (Operator Precedence) เหมือนในภาษาคณิตศาสตร์ทั่วไป เช่น การคูณจะไม่มีความสำคัญเหนือกว่าการบวก
ตัวดำเนินการ Reduce (/) ทำหน้าที่อะไร?
ตัวดำเนินการ Reduce จะนำฟังก์ชันที่อยู่ทางซ้ายของมันมาประยุกต์ใช้กับสมาชิกทุกตัวในอาเรย์เพื่อลดรูปข้อมูลให้เหลือผลลัพธ์เดียว เช่น การหาผลรวมหรือผลคูณของสมาชิกทั้งหมดในเวกเตอร์
