เก่งโค้ดงาน Business Intelligence ตอนที่ 2

เก่งโค้ดงาน Business Intelligence ตอนที่ 2
ฟังก์ชันกับตัวกระทำ
ฟังก์ชันในภาษา M เป็นการจับคู่ระหว่างค่าอินพุตกับค่าเอาต์พุต
เราสามารถเขียนนิยามฟังก์ชันได้โดยเริ่มจากการกำหนดชุดของอินพุต (ส่วนที่เป็นพารามิเตอร์ของฟังก์ชัน)
แล้วตามด้วยนิพจน์ซึ่งทำหน้าที่คำนวณสิ่งที่จะเป็นผลลัพธ์ของฟังก์ชัน (ส่วนที่เป็นไส้ของฟังก์ชัน)
โดยใส่เครื่องหมาย “ส่งไปยัง” ( => ) ไว้ระหว่างอินพุตกับนิพจน์
ยกตัวอย่างเช่น
ในรูปที่ 1 โค้ดบรรทัดที่ 3 คือ การเขียนนิยามฟังก์ชันที่สั้นสุด
สิ่งที่มันทำ คือ นำ 1 บวกเข้ากับค่าอินพุต
ส่วน (x) คือ ส่วนที่เป็นอินพุตพารามิเตอร์ของฟังก์ชัน และ
x + 1 คือ ส่วนที่เป็นไส้ของฟังก์ชัน
โปรดสังเกตว่ามีสัญลักษณ์ “ส่งไปยัง” ( => ) คั่นอยู่ตรงกลาง (ระหว่างอินพุตกับไส้)
เราสามารถเขียนนิยามฟังก์ชันได้โดยเริ่มจากการกำหนดชุดของอินพุต (ส่วนที่เป็นพารามิเตอร์ของฟังก์ชัน)
แล้วตามด้วยนิพจน์ซึ่งทำหน้าที่คำนวณสิ่งที่จะเป็นผลลัพธ์ของฟังก์ชัน (ส่วนที่เป็นไส้ของฟังก์ชัน)
โดยใส่เครื่องหมาย “ส่งไปยัง” ( => ) ไว้ระหว่างอินพุตกับนิพจน์
ยกตัวอย่างเช่น
ในรูปที่ 1 โค้ดบรรทัดที่ 3 คือ การเขียนนิยามฟังก์ชันที่สั้นสุด
สิ่งที่มันทำ คือ นำ 1 บวกเข้ากับค่าอินพุต
ส่วน (x) คือ ส่วนที่เป็นอินพุตพารามิเตอร์ของฟังก์ชัน และ
x + 1 คือ ส่วนที่เป็นไส้ของฟังก์ชัน
โปรดสังเกตว่ามีสัญลักษณ์ “ส่งไปยัง” ( => ) คั่นอยู่ตรงกลาง (ระหว่างอินพุตกับไส้)

เราสามารถกำหนดอินพุตพารามิเตอร์ของฟังก์ชันได้มากกว่าหนึ่งตัว
ยกตัวอย่างเช่น
ในรูปที่ 1 โค้ดบรรทัดที่ 5 คือ ตัวอย่างการเขียนนิยามฟังก์ชันที่มีอินพุตพารามิเตอร์สองตัวคือ x และ y
โปรดสังเกตว่าพารามิเตอร์ทั้งหมดอยู่ภายในวงเล็บเดียวกัน และในกรณีที่มีพารามิเตอร์มากกว่าหนึ่งตัว ให้คั่นแต่และตัวด้วยเครื่องหมายลูกน้ำ
ยกตัวอย่างเช่น
ในรูปที่ 1 โค้ดบรรทัดที่ 5 คือ ตัวอย่างการเขียนนิยามฟังก์ชันที่มีอินพุตพารามิเตอร์สองตัวคือ x และ y
โปรดสังเกตว่าพารามิเตอร์ทั้งหมดอยู่ภายในวงเล็บเดียวกัน และในกรณีที่มีพารามิเตอร์มากกว่าหนึ่งตัว ให้คั่นแต่และตัวด้วยเครื่องหมายลูกน้ำ
ฟังก์ชันในภาษา M ไม่มีชื่อ เป็นเพียงค่า ๆ หนึ่งเหมือนตัวเลขหรือตัวอักษร แต่เราสามารถนำฟิลด์มาผูกกับฟังกชันได้
ผลลัพธ์คือเราสามารถอ้างถึงฟังก์ชันโดยใช้ชื่อฟิลด์
ดูตัวอย่างโค้ดรูปที่ 1
บรรทัดที่ 8 เป็นการนำฟิลด์ Add มาผูกเข้ากับฟังก์ชัน (x, y) => x + y ที่มีผลให้เราสามารถอ้างถึงฟังก์ชันนี้โดยใช้ชื่อ Add
บรรทัดที่ 9 และ 10 ฟิลด์ OnePlusOne และ OnePlusTwo จะมีค่า 2 และ 3 ตามลำดับ
ผลลัพธ์คือเราสามารถอ้างถึงฟังก์ชันโดยใช้ชื่อฟิลด์
ดูตัวอย่างโค้ดรูปที่ 1
บรรทัดที่ 8 เป็นการนำฟิลด์ Add มาผูกเข้ากับฟังก์ชัน (x, y) => x + y ที่มีผลให้เราสามารถอ้างถึงฟังก์ชันนี้โดยใช้ชื่อ Add
บรรทัดที่ 9 และ 10 ฟิลด์ OnePlusOne และ OnePlusTwo จะมีค่า 2 และ 3 ตามลำดับ
ภาษา M มีไลบรารีมาตรฐานเก็บนิยามของฟังก์ชัน และ ตัวคงค่าที่ใช้บ่อยไว้ให้เราเรียกใช้ในนิพจน์ได้โดยสะดวก และ เราสามารถอ้างถึงมันได้โดยไม่ต้องระบุชื่อไลบรารี
ตัวอย่างโค้ดรูปที่ 1
บรรทัดที่ 13 อ้างถึงค่า E ซึ่งเป็นจำนวนอตรรกยะ (irrational number) ที่อยู่ภายใน Number และ
บรรทัด 14 อ้างถึงฟังก์ชัน PositionOf ซึ่งเป็นฟังก์ชันที่อยู่ภายใน Text ทั้ง Number และ Text ล้วนอยุ่ในไลบรารีมาตรฐาน
ตัวอย่างโค้ดรูปที่ 1
บรรทัดที่ 13 อ้างถึงค่า E ซึ่งเป็นจำนวนอตรรกยะ (irrational number) ที่อยู่ภายใน Number และ
บรรทัด 14 อ้างถึงฟังก์ชัน PositionOf ซึ่งเป็นฟังก์ชันที่อยู่ภายใน Text ทั้ง Number และ Text ล้วนอยุ่ในไลบรารีมาตรฐาน
ภาษา M มีตัวกระทำ (โอเปอเรเตอร์) มาให้จำนวนหนึ่ง เราใช้ตัวกระทำร่วมกับตัวถูกกระทำ (โอเปอเรนด์) เพื่อกำหนดนิยามนิพจน์
ยกตัวอย่างเช่น
บรรทัดที่ 16 คือนิพจน์ 1 และ 2 คือโอเปอเรนด์ เครื่องหมาย + คือตัวโอเปอเรเตอร์บวก
โอเปอเรเตอร์แต่ละตัวอาจมีการกระทำที่แตกต่างกันตามแต่สถานะการณ์ ยกตัวอย่างเช่น
บรรทัดที่ 16 เราใช้โอเปอเรเตอร์ + เพื่อบวกเลขจำนวนเต็มสองตัว
ขณะที่บรรทัด 17 เราใช้มันเพื่อบวกค่าของเวลาสองค่า
ยกตัวอย่างเช่น
บรรทัดที่ 16 คือนิพจน์ 1 และ 2 คือโอเปอเรนด์ เครื่องหมาย + คือตัวโอเปอเรเตอร์บวก
โอเปอเรเตอร์แต่ละตัวอาจมีการกระทำที่แตกต่างกันตามแต่สถานะการณ์ ยกตัวอย่างเช่น
บรรทัดที่ 16 เราใช้โอเปอเรเตอร์ + เพื่อบวกเลขจำนวนเต็มสองตัว
ขณะที่บรรทัด 17 เราใช้มันเพื่อบวกค่าของเวลาสองค่า
อีกตัวอย่างหนึ่ง คือ เครื่องหมาย & ก็เป็นโอเปอเรเตอร์ที่มีการกระทำที่แตกต่างกันตามแต่สถานะการณ์ ในรูปที่ 1
บรรทัดที่ 20 เป็นนิพจน์ที่นำสตริงก์สองตัวมาต่อกัน
ขณะที่บรรทัด 23 เป็นนิพจน์ที่นำลิสต์สองตัวมาต่อกัน และ
บรรทัด 24 เป็นนิพจน์ที่นำเรคคอร์ดสองเรคคอร์มาผสมกัน
จะเห็นว่าทั้งสามนิพจน์เป็นการกระทำที่แตกต่างกันแต่ล้วนใช้ตัวกระทำ &
บรรทัดที่ 20 เป็นนิพจน์ที่นำสตริงก์สองตัวมาต่อกัน
ขณะที่บรรทัด 23 เป็นนิพจน์ที่นำลิสต์สองตัวมาต่อกัน และ
บรรทัด 24 เป็นนิพจน์ที่นำเรคคอร์ดสองเรคคอร์มาผสมกัน
จะเห็นว่าทั้งสามนิพจน์เป็นการกระทำที่แตกต่างกันแต่ล้วนใช้ตัวกระทำ &
ข้อควรระวังคือใช่ว่าค่าทุกแบบนำจะมาต่อกันหรือบวกกันด้วยเครื่องหมาย + ได้ทั้งหมด
ยกตัวอย่างเช่นในรูปที่ 1
บรรทัดที่ 26 จะ Error เพราะภาษา M ไม่สนับสนุนการนำตัวเลขกับตัวอักษรมาบวกกัน
ยกตัวอย่างเช่นในรูปที่ 1
บรรทัดที่ 26 จะ Error เพราะภาษา M ไม่สนับสนุนการนำตัวเลขกับตัวอักษรมาบวกกัน

เมตาดาต้า
เมตาดาต้า (Metadata แปลว่าข้อมูลเกี่ยวกับข้อมูล)
ในภาษา M เมตาดาต้าอยู่ในรูปของเรคคอร์ดเรียกว่า “เมตาดาต้าเรคคอร์ด” (Metadata Record : MR) ที่ประกอบด้วยฟิลด์ต่าง ๆ ใช้ทำหน้าที่เก็บเมตาดาต้า
ตัวเก็บค่าทุกตัวจะมี MR แต่ถ้าตัวเก็บค่านั้นไม่มีเมตาดาต้า ตัวเรคคอร์ดจะยังมีแต่จะว่างเปล่า (คือเป็นเรคคอร์ดที่ไม่มีฟิลด์)
ในภาษา M เมตาดาต้าอยู่ในรูปของเรคคอร์ดเรียกว่า “เมตาดาต้าเรคคอร์ด” (Metadata Record : MR) ที่ประกอบด้วยฟิลด์ต่าง ๆ ใช้ทำหน้าที่เก็บเมตาดาต้า
ตัวเก็บค่าทุกตัวจะมี MR แต่ถ้าตัวเก็บค่านั้นไม่มีเมตาดาต้า ตัวเรคคอร์ดจะยังมีแต่จะว่างเปล่า (คือเป็นเรคคอร์ดที่ไม่มีฟิลด์)
ภาษา M ใช้เมตาดาต้าเพื่อเก็บข้อมูลอะไรก็ได้ เพิ่มเติมให้แก่ตัวเก็บค่าตัวหนึ่ง ๆ โดยไม่เปลี่ยนแปลงพฤติกรรมหรือค่าของตัวเก็บค่านั้น ๆ
หากเราต้องการกำหนด MR ของตัวเก็บค่า x เป็นค่า y ซินแทกซ์จะเป็น x meta y
ยกตัวอย่างเช่นในรูปที่ 2
บรรทัด 3 ตัวเก็บค่าคือข้อความตัวอักษร “Mozart” ถูกกำหนดให้มี MR ที่มีสองฟิลด์คือ Rating และ Tags
หากเราต้องการกำหนด MR ของตัวเก็บค่า x เป็นค่า y ซินแทกซ์จะเป็น x meta y
ยกตัวอย่างเช่นในรูปที่ 2
บรรทัด 3 ตัวเก็บค่าคือข้อความตัวอักษร “Mozart” ถูกกำหนดให้มี MR ที่มีสองฟิลด์คือ Rating และ Tags
ถ้าเรามีตัวเก็บค่า ๆ หนึ่งที่มี MR แล้ว เราสามารถเพิ่มฟิลด์ใหม่ให้แก่ MR ได้โดยใช้ตัวกระทำ meta หรือ & อย่างใดอย่างหนึ่ง
ยกตัวอย่างเช่นในรูปที่ 2
บรรทัด 5 เรามีตัวเก็บค่าคือข้อความตัวอักษร “Mozart” ที่มี MR ที่มีฟิลด์เดียวคือ Rating และเราต้องการเพิ่มฟิลด์ใหม่คือ Tag ก็ทำได้โดยใช้คำสั่ง meta (บรรทัดที่ 5) หรือใช้ & อย่างที่เห็นในบรรทัดที่ 6 สองบรรทัดนี้ให้ผลลัพธ์เหมือนกัน
ยกตัวอย่างเช่นในรูปที่ 2
บรรทัด 5 เรามีตัวเก็บค่าคือข้อความตัวอักษร “Mozart” ที่มี MR ที่มีฟิลด์เดียวคือ Rating และเราต้องการเพิ่มฟิลด์ใหม่คือ Tag ก็ทำได้โดยใช้คำสั่ง meta (บรรทัดที่ 5) หรือใช้ & อย่างที่เห็นในบรรทัดที่ 6 สองบรรทัดนี้ให้ผลลัพธ์เหมือนกัน
ส่วนการอ่านหรือการดึงค่าของเมตาดาต้าทำได้โดยใช้ฟังก์ชัน Value.Metadata (อยู่ในไลบรารีมาตรฐาน)
ยกตัวอย่างเช่นในรูปที่ 2
บรรทัด 9 เรามีค่าคือข้อความตัวอักษร “Mozart” ซึ่งมีเมตาดาต้าสองตัวคือ Rating และ Tags และเรานำตัวเก็บค่านี้ผูกกับตัวแปรชื่อ Composer
เมื่อต้องการดึงหรืออ่านค่า Rating ก็ทำได้โดยใช้ฟังก์ชัน Value.Metadata กำหนดอินพุตพารามิเตอร์เป็นชื่อของตัวแปรอ้างอิงคือ Composer ไว้ในวงเล็บ หลังวงเล็บใส่วงเล็บเหลี่ยมและชื่อของ MR ฟิลด์ที่ต้องการคือ Rating
ยกตัวอย่างเช่นในรูปที่ 2
บรรทัด 9 เรามีค่าคือข้อความตัวอักษร “Mozart” ซึ่งมีเมตาดาต้าสองตัวคือ Rating และ Tags และเรานำตัวเก็บค่านี้ผูกกับตัวแปรชื่อ Composer
เมื่อต้องการดึงหรืออ่านค่า Rating ก็ทำได้โดยใช้ฟังก์ชัน Value.Metadata กำหนดอินพุตพารามิเตอร์เป็นชื่อของตัวแปรอ้างอิงคือ Composer ไว้ในวงเล็บ หลังวงเล็บใส่วงเล็บเหลี่ยมและชื่อของ MR ฟิลด์ที่ต้องการคือ Rating

นิพจน์ Let
ภาษา M มีลักษณะเป็นคิวรีเช่นเดียวกับภาษา SQL
ภาษา SQL โครงหลักของคิวรีคือคำสั่ง Select/From
ภาษา M โครงหลักของคิวรีคือคำสั่ง Let/In
โดยนิพจน์ Let จะมีไส้เป็นกลุ่มโค้ดเพื่อการคำนวณค่าและการกำหนดชื่อให้แก่ค่า ปิดท้ายด้วยคำสั่ง In ซึ่งทำหน้าที่สรุปด้วยการนำค่าต่าง ๆ ในไส้ของ Let มาใช้งาน
ภาษา SQL โครงหลักของคิวรีคือคำสั่ง Select/From
ภาษา M โครงหลักของคิวรีคือคำสั่ง Let/In
โดยนิพจน์ Let จะมีไส้เป็นกลุ่มโค้ดเพื่อการคำนวณค่าและการกำหนดชื่อให้แก่ค่า ปิดท้ายด้วยคำสั่ง In ซึ่งทำหน้าที่สรุปด้วยการนำค่าต่าง ๆ ในไส้ของ Let มาใช้งาน
ยกตัวอย่างเช่น รูปที่ 3
ส่วนไส้ของนิพจน์ Let คือ ระหว่างบรรทัดที่ 4 ถึง 17 และ
ส่วน In คือบรรทัด 18 ในไส้มีนิยามค่าสองค่าคือ เรคคอร์ด Sales2007 และ Sales2008
ส่วนใน In อ้างถึงฟิลด์ Total ของ Sales2007 และ Sales2008 ที่อยู่ในบรรทัดที่ 9 และ 16 ตามลำดับ
ส่วนไส้ของนิพจน์ Let คือ ระหว่างบรรทัดที่ 4 ถึง 17 และ
ส่วน In คือบรรทัด 18 ในไส้มีนิยามค่าสองค่าคือ เรคคอร์ด Sales2007 และ Sales2008
ส่วนใน In อ้างถึงฟิลด์ Total ของ Sales2007 และ Sales2008 ที่อยู่ในบรรทัดที่ 9 และ 16 ตามลำดับ

นิพจน์ If
คำสั่งเพื่อใช้ในการตัดสินใจทุกภาษาใช้คำสั่ง If ภาษา M ก็ไม่เว้น
Syntax เป็นอย่างในรูปที่ 4
บรรทัด 4-7 คำว่า test คือ นิพจน์หรือค่าที่ให้ผลลัพธ์เป็นจริงหรือเท็จ (คือเป็นค่าแบบตรรก)
บรรทัดที่ 5 คือคำสั่งที่จะทำงานหากเงื่อนไขของนิพจน์เป็นจริง
บรรทัดที่ 7 คือคำสั่งที่จะทำงานหากเงื่อนไขเป็นเท็จ
Syntax เป็นอย่างในรูปที่ 4
บรรทัด 4-7 คำว่า test คือ นิพจน์หรือค่าที่ให้ผลลัพธ์เป็นจริงหรือเท็จ (คือเป็นค่าแบบตรรก)
บรรทัดที่ 5 คือคำสั่งที่จะทำงานหากเงื่อนไขของนิพจน์เป็นจริง
บรรทัดที่ 7 คือคำสั่งที่จะทำงานหากเงื่อนไขเป็นเท็จ
ประโยคเงื่อนไขในคำสั่ง if มักประกอบด้วยตัวกระทำเปรียบเทียบ เช่น เท่ากับ (=) ไม่เท่ากับ (<>) มากกว่า (>) น้อยกว่า (<) และอื่น ๆ
ยกตัวอย่างเช่นในรูปที่ 4
บรรทัด 9 ใช้ตัวกระทำ “มากกว่า” > เพื่อตรวจสอบค่า ผลลัพธ์ของการเปรียบเทียบย่อมเป็นจริงหรือเท็จ (true/false หรือ Yes/No) เท่านั้น
ยกตัวอย่างเช่นในรูปที่ 4
บรรทัด 9 ใช้ตัวกระทำ “มากกว่า” > เพื่อตรวจสอบค่า ผลลัพธ์ของการเปรียบเทียบย่อมเป็นจริงหรือเท็จ (true/false หรือ Yes/No) เท่านั้น
บรรทัด 15 ใช้ตัวกระทำ “เท่ากับ” = เพื่อตรวจสอบว่าฟิลด์ที่ระบุมีค่าเป็น A หรือไม่
นิพจน์เงื่อนไขนี้อาจมีฟังก์ชันมาอยู่ร่วมด้วยก็ได้
ยกตัวอย่างเช่นรูปที่ 4
บรรทัดที่ 20 ใช้ฟังก์ชัน Text.Range เพื่อกำหนดตำแหน่งและขนาดของตัวอักษรที่ต้องการเปรียบเทียบ
นิพจน์เงื่อนไขนี้อาจมีฟังก์ชันมาอยู่ร่วมด้วยก็ได้
ยกตัวอย่างเช่นรูปที่ 4
บรรทัดที่ 20 ใช้ฟังก์ชัน Text.Range เพื่อกำหนดตำแหน่งและขนาดของตัวอักษรที่ต้องการเปรียบเทียบ
นิพจน์เงื่อนไขนี้อาจมีนิพจน์ย่อยหลายอันนำมาต่อเชื่อมกันก็ได้
ยกตัวอย่างเช่นรูปที่ 4
บรรทัด 25 ส่วนที่เป็นนิพจน์เงื่อนไขประกอบด้วยนิพจน์ย่อยสองอัน
ยกตัวอย่างเช่นรูปที่ 4
บรรทัด 25 ส่วนที่เป็นนิพจน์เงื่อนไขประกอบด้วยนิพจน์ย่อยสองอัน
- อันแรกคือ [Delivery Date] <> null
- อันที่สองคือ [Order Type] = "In Store Pickup"
สองนิพจน์นี้ถูกนำมาเชื่อมกันโดยคำสั่ง or ที่ทำให้เกิดเป็นนิพจน์บูลีน

การจัดการ Error
การเขียนโค้ดกับ Error เป็นของคู่กัน
Error ในหัวข้อนี้หมายถึงเมื่อเราป้อนพิมพ์โค้ดแล้วตัวแปลภาษาไม่สามารถประมวลผลให้เกิดผลลัพธ์ได้เพราะเราเขียนอะไรผิดไว้ที่ใดสักแห่งในโค้ด
Error จะเกิดขึ้นเมื่อตัว run time พยายามที่จะหาค่าของตัวกระทำหรือฟังก์ชันหรือ Run นิพจน์ Error
Error ในหัวข้อนี้หมายถึงเมื่อเราป้อนพิมพ์โค้ดแล้วตัวแปลภาษาไม่สามารถประมวลผลให้เกิดผลลัพธ์ได้เพราะเราเขียนอะไรผิดไว้ที่ใดสักแห่งในโค้ด
Error จะเกิดขึ้นเมื่อตัว run time พยายามที่จะหาค่าของตัวกระทำหรือฟังก์ชันหรือ Run นิพจน์ Error
ในภาษา M เราสามารถรับมือหรือดัก Error ได้โดยใช้นิพจน์คำสั่ง try
ตัวอย่างโค้ดในรูปที่ 5
บรรทัด 3-13 แสดงการใช้คำสั่ง try
ผลลัพธ์การทำงานจะเป็นอย่างบรรทัด 15 ถ้าค่าของ Units ไม่ใช่ศูนย์
หากเป็นศูนย์ผลลัพธ์จะเป็นอย่างบรรทัดที่ 16
ให้สังเกตคำว่า HasError, Error และ Message
สามคำนี้มีที่มาจากนิพจน์ try จะแปลงค่า และ Error ไปเป็นเรคคอร์ดที่ระบุว่าเกิด Error หรือไม่
ซึ่งมีโครงสร้างอย่างที่เห็นใน รูปที่ 5 บรรทัด 20-28
ตัวอย่างโค้ดในรูปที่ 5
บรรทัด 3-13 แสดงการใช้คำสั่ง try
ผลลัพธ์การทำงานจะเป็นอย่างบรรทัด 15 ถ้าค่าของ Units ไม่ใช่ศูนย์
หากเป็นศูนย์ผลลัพธ์จะเป็นอย่างบรรทัดที่ 16
ให้สังเกตคำว่า HasError, Error และ Message
สามคำนี้มีที่มาจากนิพจน์ try จะแปลงค่า และ Error ไปเป็นเรคคอร์ดที่ระบุว่าเกิด Error หรือไม่
ซึ่งมีโครงสร้างอย่างที่เห็นใน รูปที่ 5 บรรทัด 20-28

Source Code ภาษา M
ภาษา M มีความอ่อนไหวต่อตัวอักษรเล็ก-ใหญ่ (case sensitive)
ดังนั้นตัวแปร abc, Abc, abC, ABC, aBc ถือว่าเป็นคนละตัวกัน
การเขียนหมายเหตุ (comment)
ดังนั้นตัวแปร abc, Abc, abC, ABC, aBc ถือว่าเป็นคนละตัวกัน
การเขียนหมายเหตุ (comment)
- แบบบรรทัดเดียวใช้เครื่องหมาย //
- แบบหลายบรรทัดใช้ /* */ (ดูรูปที่ 6 บรรทัด 2-7)
การป้อนพิมพ์โค้ดจะเขียนติดกันหมดเป็นบรรทัดเดียว (ดูรูปที่ 6 บรรทัด 9) หรือ
จะจัดรูปแบบซอร์สโค้ดให้อ่านง่ายโดยใส่บรรทัดใหม่และย่อหน้า (ดูรูปที่ 6 บรรทัด 11-16) ก็ได้
โดยไม่มีผลต่อการทำงานของโปรแกรม
จะจัดรูปแบบซอร์สโค้ดให้อ่านง่ายโดยใส่บรรทัดใหม่และย่อหน้า (ดูรูปที่ 6 บรรทัด 11-16) ก็ได้
โดยไม่มีผลต่อการทำงานของโปรแกรม
ภาษา M มี Escape Code: EC และ Escape Sequence: ES
เพื่อให้สามารถป้อนพิมพ์รหัสบางอย่างที่ป้อนโดยใช้วิธีตามปรกติไม่ได้
การป้อน EC ให้เริ่มด้วยเครื่องหมาย # ตามด้วยโค้ดที่ต้องการ
ยกตัวอย่างเช่น รูปที่ 6
บรรทัด 18 คือ EC ที่เราป้อนเมื่อต้องการเครื่องหมาย # เอง
บรรทัด 19 คือ EC เมื่อต้องการเลขฐานสิบหก
บรรทัด 21 คือ EC เมื่อต้องการโค้ด “รีเทิน”
บรรทัด 22 และ 23 คือตัวอย่างการป้อน ES เมื่อต้องการรีเทินและขึ้นบรรทัดใหม่
บรรทัด 25 คือต้องการแสดงข้อความว่า Hello world แล้วเลื่อนเคอร์เซอร์ไปซ้ายสุด แล้วขึ้นบรรทัดใหม่ด้วย
เพื่อให้สามารถป้อนพิมพ์รหัสบางอย่างที่ป้อนโดยใช้วิธีตามปรกติไม่ได้
การป้อน EC ให้เริ่มด้วยเครื่องหมาย # ตามด้วยโค้ดที่ต้องการ
ยกตัวอย่างเช่น รูปที่ 6
บรรทัด 18 คือ EC ที่เราป้อนเมื่อต้องการเครื่องหมาย # เอง
บรรทัด 19 คือ EC เมื่อต้องการเลขฐานสิบหก
บรรทัด 21 คือ EC เมื่อต้องการโค้ด “รีเทิน”
บรรทัด 22 และ 23 คือตัวอย่างการป้อน ES เมื่อต้องการรีเทินและขึ้นบรรทัดใหม่
บรรทัด 25 คือต้องการแสดงข้อความว่า Hello world แล้วเลื่อนเคอร์เซอร์ไปซ้ายสุด แล้วขึ้นบรรทัดใหม่ด้วย

ชื่ออะไรต่าง ๆ ที่เรานิยามขึ้นเอง (เช่นตัวแปร ฟิลด์ และเรคคอร์ด)
ในหนึ่งชื่อต้องเขียนติดกันทั้งหมด จะใส่เคาะวรรคไม่ได้
ถ้าอยากจะได้ชื่อที่มีวรรคอย่าง “1998 Sales” ต้องใส่ EC นำหน้า
ยกตัวอย่างเช่นรูปที่ 7
บรรทัด 5-8 เป็นการนิยามและการอ้างชื่อแบบที่ว่ามานี้
บรรทัด 10-14 แสดงให้เห็นว่าเมื่อใช้ EC เราอาจใส่ตัวกระทำ (เช่นเครื่องหมาย +) ไว้ในชื่อก็ได้
ในบางกรณีเราอาจกำหนดชื่อที่มีเคาะวรรคได้เหมือนกัน
โดยมีข้อแม้ว่าต้องใช้ภายในตำแหน่งที่ไม่ก่อให้เกิดความกำกวม
ยกตัวอย่างเช่นเมื่ออยู่ภายในเครื่องหมาย [ ] รูปที่ 7
บรรทัด 16-19 แสดงตัวอย่างที่พูดถึงนี้
ในหนึ่งชื่อต้องเขียนติดกันทั้งหมด จะใส่เคาะวรรคไม่ได้
ถ้าอยากจะได้ชื่อที่มีวรรคอย่าง “1998 Sales” ต้องใส่ EC นำหน้า
ยกตัวอย่างเช่นรูปที่ 7
บรรทัด 5-8 เป็นการนิยามและการอ้างชื่อแบบที่ว่ามานี้
บรรทัด 10-14 แสดงให้เห็นว่าเมื่อใช้ EC เราอาจใส่ตัวกระทำ (เช่นเครื่องหมาย +) ไว้ในชื่อก็ได้
ในบางกรณีเราอาจกำหนดชื่อที่มีเคาะวรรคได้เหมือนกัน
โดยมีข้อแม้ว่าต้องใช้ภายในตำแหน่งที่ไม่ก่อให้เกิดความกำกวม
ยกตัวอย่างเช่นเมื่ออยู่ภายในเครื่องหมาย [ ] รูปที่ 7
บรรทัด 16-19 แสดงตัวอย่างที่พูดถึงนี้
ภาษา M มีคำสั่งที่เป็นคำสงวน (คือคำที่คนเขียนโค้ดนำไปกำหนดเป็นชื่อของตัวเก็บค่าต่าง ๆ ไม่ได้) อยู่ไม่มากนัก อย่างที่เห็นใน รูปที่ 7
บรรทัด 22-25 และมีตัวกระทำและตัวกำหนดวรรคตอนอย่างที่เห็นในรูปที่ 7 บรรทัดที่ 28
สภาพแวดล้อม
ภาษา M อาศัยสิ่งที่เรียกว่า “สภาพแวดล้อม” (Environments) เพื่อการแบ่งกลุ่มตัวแปร
สภาพแวดล้อมมีได้หลายตัว เมื่อมีหลายตัวจะมีโครงสร้างเป็นลำดับชั้น
ชั้นบนสุดหรือระดับสูงสุดเรียกว่า สภาพแวดล้อมกลาง (global environment หรือ root ก็ว่า)
เป็นสภาพแวดล้อมที่ระบบจะสร้างให้เองโดยอัตโนมัติ ไม่ได้เกิดจากการทำงานของโค้ดของเรา
นอกจากตัวแปรแล้วสิ่งที่อยู่ภายในสภาพแวดล้อมกลางยังประกอบด้วยค่าต่าง ๆ ที่มาจากไลบรารี (เช่นตัวคงค่า) ด้วย
สภาพแวดล้อมมีได้หลายตัว เมื่อมีหลายตัวจะมีโครงสร้างเป็นลำดับชั้น
ชั้นบนสุดหรือระดับสูงสุดเรียกว่า สภาพแวดล้อมกลาง (global environment หรือ root ก็ว่า)
เป็นสภาพแวดล้อมที่ระบบจะสร้างให้เองโดยอัตโนมัติ ไม่ได้เกิดจากการทำงานของโค้ดของเรา
นอกจากตัวแปรแล้วสิ่งที่อยู่ภายในสภาพแวดล้อมกลางยังประกอบด้วยค่าต่าง ๆ ที่มาจากไลบรารี (เช่นตัวคงค่า) ด้วย
แนวคิดเรื่อสภาพแวดล้อมคล้าย ๆ กับเรื่องแนมสเปส (name space) หรือเรื่องสโคป (scope) ในภาษาตระกูลซี
คือ มีไว้เพื่อกำหนดขอบเขตของค่าต่าง ๆ เพื่อป้องการความสับสนกำกวมในการอ้างอิง
สภาพแวดล้อมจะเกิดขึ้นเองเมื่อตัวแปลภาษาประมวลผลนิพจน์ที่ทำให้เกิดค่าต่าง ๆ จากโค้ดของเรา
คือ มีไว้เพื่อกำหนดขอบเขตของค่าต่าง ๆ เพื่อป้องการความสับสนกำกวมในการอ้างอิง
สภาพแวดล้อมจะเกิดขึ้นเองเมื่อตัวแปลภาษาประมวลผลนิพจน์ที่ทำให้เกิดค่าต่าง ๆ จากโค้ดของเรา

สภาพแวดล้อมจะรับรู้ถึงค่าทุกค่าที่อยู่ในสภาพแวดล้อมนั้น ยกเว้นค่าที่กำลังถูกประมวลผล
ยกตัวอย่างเช่น รูปที่ 8
บรรทัดที่ 3 ถึง 7 คือ นิยามเรคคอร์ดที่ประกอบด้วยสามฟิลด์ (x, y และ z)
ขณะที่โปรแกรมทำงานบรรทัดที่ 4 สภาพแวดล้อมจะรับรู้ถึงฟิลด์อื่น ๆ ที่เหลือ (คือ y และ z)
ยกเว้นฟิลด์ที่กำลังถูกประเมินค่าอยู่ในขณะนั้น (คือ x)
ในทำนองเดียวกันขณะที่โปรแกรมทำงานบรรทัดที่ 5 สภาพแวดล้อมจะรับรู้ถึงฟิลด์อื่น ๆ ที่เหลือ (คือ x และ z)
ยกเว้นฟิลด์ที่กำลังถูกประเมินค่าอยู่ในขณะนั้น (คือ y)
ยกตัวอย่างเช่น รูปที่ 8
บรรทัดที่ 3 ถึง 7 คือ นิยามเรคคอร์ดที่ประกอบด้วยสามฟิลด์ (x, y และ z)
ขณะที่โปรแกรมทำงานบรรทัดที่ 4 สภาพแวดล้อมจะรับรู้ถึงฟิลด์อื่น ๆ ที่เหลือ (คือ y และ z)
ยกเว้นฟิลด์ที่กำลังถูกประเมินค่าอยู่ในขณะนั้น (คือ x)
ในทำนองเดียวกันขณะที่โปรแกรมทำงานบรรทัดที่ 5 สภาพแวดล้อมจะรับรู้ถึงฟิลด์อื่น ๆ ที่เหลือ (คือ x และ z)
ยกเว้นฟิลด์ที่กำลังถูกประเมินค่าอยู่ในขณะนั้น (คือ y)
ในกรณีคำสั่ง let / in ก็คล้าย ๆ กัน คือ สภาพแวดล้อมจะรับรู้ถึงค่าทุกค่าที่อยู่ในสภาพแวดล้อมนั้น
ยกเว้นค่าที่กำลังถูกประมวลผล
ยกตัวอย่างเช่น รูปที่ 8
บรรทัดที่ 10 ถึง 12 คือ การประกาศและกำหนดค่าให้แก่ตัวแปรสามตัว (ได้แก่ x, y และ z)
ขณะที่โปรแกรมทำงานบรรทัดที่ 10 สภาพแวดล้อมจะรับรู้ถึงตัวแปรอื่น ๆ ที่เหลือ (y และ z)
ยกเว้นตัวแปรที่กำลังถูกประเมินค่าอยู่ในขณะนั้น (x)
ในทำนองเดียวกันขณะที่โปรแกรมทำงานบรรทัดที่ 11 สภาพแวดล้อมจะรับรู้ถึงตัวแปรอื่น ๆ ที่เหลือ (x และ z)
ยกเว้นตัวแปรที่กำลังถูกประเมินค่าอยู่ในขณะนั้น (y)
ขณะที่บรรทัด 14 ในคำสั่ง in จะรับรู้ถึงตัวแปรทุกตัวที่อยู่ในสภาพแวดล้อมของ let
ยกเว้นค่าที่กำลังถูกประมวลผล
ยกตัวอย่างเช่น รูปที่ 8
บรรทัดที่ 10 ถึง 12 คือ การประกาศและกำหนดค่าให้แก่ตัวแปรสามตัว (ได้แก่ x, y และ z)
ขณะที่โปรแกรมทำงานบรรทัดที่ 10 สภาพแวดล้อมจะรับรู้ถึงตัวแปรอื่น ๆ ที่เหลือ (y และ z)
ยกเว้นตัวแปรที่กำลังถูกประเมินค่าอยู่ในขณะนั้น (x)
ในทำนองเดียวกันขณะที่โปรแกรมทำงานบรรทัดที่ 11 สภาพแวดล้อมจะรับรู้ถึงตัวแปรอื่น ๆ ที่เหลือ (x และ z)
ยกเว้นตัวแปรที่กำลังถูกประเมินค่าอยู่ในขณะนั้น (y)
ขณะที่บรรทัด 14 ในคำสั่ง in จะรับรู้ถึงตัวแปรทุกตัวที่อยู่ในสภาพแวดล้อมของ let
โปรดสังเกตว่าคำสั่ง let / in มีผลให้เกิดสภาพแวดล้อมสองตัว
ตัวแรกคือสภาพแวดล้อมของ let
ตัวที่สองคือสภาพแวดล้อมของ in
และไม่ใช่เฉพาะคำสั่ง let / in ที่มีผลให้เกิดสภาพแวดล้อมสองตัว
การนิยามเรคคอร์ดซ้อนเรคคอร์ดก็มีผลให้เกิดสภาพแวดล้อมสองตัวด้วยเช่นกัน
ยกตัวอย่างเช่น
บรรทัด 16-24 คือโค้ดที่นิยามเรคคอร์ดซ้อนเรคคอร์ด คือ มีเรคคอร์ดนี้มีสองฟิลด์ (a และ b) โดยที่ฟิลด์ a มีค่าจากเรคคอร์ดอีกที่หนึ่ง
จะเห็นว่าเกิดสภาพแวดล้อมสองตัว
ตัวแรกคือบรรทัด 19-21 ซึ่งเป็นสภาพแวดล้อมที่มี x, y และ z และยังมี b ที่อยู่ใน “สภาพแวดล้อมแม่” เพิ่มมาด้วยอีกตัวหนึ่ง (ไม่มี a)
สภาพแวดล้อมที่สองคือบรรทัด 17-23 ซึ่งเป็นสภาพแวดล้อมที่มีเฉพาะ a เพียงตัวเดียว (ไม่มี b)
ตัวแรกคือสภาพแวดล้อมของ let
ตัวที่สองคือสภาพแวดล้อมของ in
และไม่ใช่เฉพาะคำสั่ง let / in ที่มีผลให้เกิดสภาพแวดล้อมสองตัว
การนิยามเรคคอร์ดซ้อนเรคคอร์ดก็มีผลให้เกิดสภาพแวดล้อมสองตัวด้วยเช่นกัน
ยกตัวอย่างเช่น
บรรทัด 16-24 คือโค้ดที่นิยามเรคคอร์ดซ้อนเรคคอร์ด คือ มีเรคคอร์ดนี้มีสองฟิลด์ (a และ b) โดยที่ฟิลด์ a มีค่าจากเรคคอร์ดอีกที่หนึ่ง
จะเห็นว่าเกิดสภาพแวดล้อมสองตัว
ตัวแรกคือบรรทัด 19-21 ซึ่งเป็นสภาพแวดล้อมที่มี x, y และ z และยังมี b ที่อยู่ใน “สภาพแวดล้อมแม่” เพิ่มมาด้วยอีกตัวหนึ่ง (ไม่มี a)
สภาพแวดล้อมที่สองคือบรรทัด 17-23 ซึ่งเป็นสภาพแวดล้อมที่มีเฉพาะ a เพียงตัวเดียว (ไม่มี b)

เราอาจนิยามเรคคอร์ดซ้อนเรคคอร์ดโดยใช้คำสั่ง let ก็ได้
รูปที่ 9 บรรทัด 3-12 คือโค้ดตัวอย่างการนิยามเรคคอร์ดซ้อนเรคคอร์ด โดยใช้คำสั่ง let
โปรดสังเกตว่าการทำเช่นนี้มีผลให้เกิดสภาพแวดล้อมขึ้นถึงสามตัว
ตัวแรกคือบรรทัด 6-8
ตัวที่สองคือบรรทัด 4-10 และ
ตัวที่สามคือสภาพแวดล้อมของ in ที่บรรทัด 12
รูปที่ 9 บรรทัด 3-12 คือโค้ดตัวอย่างการนิยามเรคคอร์ดซ้อนเรคคอร์ด โดยใช้คำสั่ง let
โปรดสังเกตว่าการทำเช่นนี้มีผลให้เกิดสภาพแวดล้อมขึ้นถึงสามตัว
ตัวแรกคือบรรทัด 6-8
ตัวที่สองคือบรรทัด 4-10 และ
ตัวที่สามคือสภาพแวดล้อมของ in ที่บรรทัด 12
ในกรณีที่มีค่าซึ่งมีชื่อเดียวกันแต่อยู่คนละสภาพแวดล้อม ตัวแปลภาษาจะถือว่าเป็นค่าคนละตัวกัน
ยกตัวอย่างเช่น รูปที่ 9
บรรทัด 14-23 ซึ่งเป็นนิยามเรคคอร์ด จะเห็นว่ามีสองฟิลด์ที่มีชื่อซ้ำกัน ได้แก่ ฟิลด์ x ในบรรทัดที่ 17 กับฟิลด์ x ในบรรทัดที่ 22
ในกรณีนี้จะถือว่า ฟิลด์ x ในบรรทัดที่ 17 เป็น “ตัวใน” (inner) ขณะที่ฟิลด์ x ในบรรทัดที่ 22 เป็น “ตัวนอก” (outer)
จะเห็นว่าสภาพแวดล้อมนอก (บรรทัด 21,22) เห็นเฉพาะ x ตัวนอก
ขณะที่สภาพแวดล้อมใน (บรรทัด 17-19) มองเห็นทั้ง x ที่เป็นตัวในและตัวนอก
ยกตัวอย่างเช่น รูปที่ 9
บรรทัด 14-23 ซึ่งเป็นนิยามเรคคอร์ด จะเห็นว่ามีสองฟิลด์ที่มีชื่อซ้ำกัน ได้แก่ ฟิลด์ x ในบรรทัดที่ 17 กับฟิลด์ x ในบรรทัดที่ 22
ในกรณีนี้จะถือว่า ฟิลด์ x ในบรรทัดที่ 17 เป็น “ตัวใน” (inner) ขณะที่ฟิลด์ x ในบรรทัดที่ 22 เป็น “ตัวนอก” (outer)
จะเห็นว่าสภาพแวดล้อมนอก (บรรทัด 21,22) เห็นเฉพาะ x ตัวนอก
ขณะที่สภาพแวดล้อมใน (บรรทัด 17-19) มองเห็นทั้ง x ที่เป็นตัวในและตัวนอก