← กลับไปยังบทความทั้งหมด

ไวยากรณ์และสัญลักษณ์ของภาษา 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 จะนำฟังก์ชันที่อยู่ทางซ้ายของมันมาประยุกต์ใช้กับสมาชิกทุกตัวในอาเรย์เพื่อลดรูปข้อมูลให้เหลือผลลัพธ์เดียว เช่น การหาผลรวมหรือผลคูณของสมาชิกทั้งหมดในเวกเตอร์