ฟังก์ชันแลมบ์ดา

ฟังก์ชัน Lambda ใน Scheme เป็นฟังก์ชันที่ไม่ระบุชื่อ ซึ่งหมายความว่าเป็นฟังก์ชันที่ไม่มีชื่อ ฟังก์ชันเหล่านี้ถูกกำหนดไว้แบบอินไลน์ และโดยทั่วไปจะใช้สำหรับการดำเนินการระยะสั้นแบบครั้งเดียว โครงสร้าง lambda เป็นเครื่องมือที่ทรงพลังในการเขียนโปรแกรมเชิงฟังก์ชัน ช่วยให้คุณสร้างตรรกะที่กระชับและยืดหยุ่นได้ทันที

ฟังก์ชัน Lambda มีประโยชน์อย่างยิ่งเมื่อ:

  • คุณต้องมีฟังก์ชันเล็กๆ เพื่อจุดประสงค์เฉพาะชั่วคราว
  • การส่งผ่านฟังก์ชันเป็นอาร์กิวเมนต์ไปยังฟังก์ชันที่มีลำดับสูงกว่า เช่น map, filter หรือ fold
  • การคืนค่าฟังก์ชันจากฟังก์ชันอื่น

ไวยากรณ์ของฟังก์ชันแลมบ์ดา

ฟังก์ชัน Lambda สามารถกำหนดได้ด้วยตัวเอง…

(lambda (parameter1 parameter2 ...)
  body-expression)

…หรือเรียกใช้ทันที:

((lambda (parameter1 parameter2 ...)
   body-expression)
 argument1 argument2 ...)
  • parameter1, parameter2, ...: พารามิเตอร์ที่ฟังก์ชันยอมรับ
  • body-expression: ตรรกะที่ดำเนินการเมื่อมีการเรียกใช้ฟังก์ชัน
  • การร้องขอทันที: รูปแบบที่ 2 แสดงแลมบ์ดาที่ถูกเรียกพร้อมอาร์กิวเมนต์ทันที

ตัวอย่างของฟังก์ชันแลมบ์ดา

การใช้ Lambda เพื่อการคำนวณอย่างง่าย

((lambda (x y) (+ x y)) 3 5)  ; Returns 8

ที่นี่:

  • ฟังก์ชันแลมบ์ดาถูกสร้างขึ้นเพื่อเพิ่มตัวเลขสองตัว (x และ y)
  • ฟังก์ชันนี้จะถูกเรียกใช้ทันทีด้วยอาร์กิวเมนต์ 3 และ 5

ฟังก์ชัน Lambda แบบอินไลน์

ตัวอย่างต่อไปนี้สาธิตวิธีใช้ for-each กับทั้งฟังก์ชันที่มีชื่อและฟังก์ชัน lambda:

การใช้ฟังก์ชันที่มีชื่อ:

(define (print-item x)
  (lumi-message (number->string x)))

(for-each print-item (list 1 2 3 4))
  • คำอธิบาย:
    • print-item เป็นฟังก์ชันที่มีชื่อซึ่งแปลงตัวเลขเป็นสตริง (number->string) และพิมพ์โดยใช้ lumi-message
    • for-each ใช้ print-item กับแต่ละองค์ประกอบในรายการ (1 2 3 4)

เอาต์พุต: 1 2 3 4

การใช้ฟังก์ชันแลมบ์ดา:

ตรรกะเดียวกันนี้สามารถเขียนแบบอินไลน์ด้วยฟังก์ชัน lambda ได้ โดยไม่จำเป็นต้องใช้ฟังก์ชันที่มีชื่อแยกต่างหาก:

(for-each (lambda (x) (lumi-message (number->string x)))
  (list 1 2 3 4))
  • คำอธิบาย:
    • (lambda (x) (lumi-message (number->string x))) กำหนดฟังก์ชันที่ไม่ระบุชื่อ
    • ฟังก์ชันนี้ใช้กับแต่ละองค์ประกอบของรายการ (1 2 3 4) โดย for-each

เอาต์พุต: 1 2 3 4

ฟังก์ชั่นแลมบ์ดาเป็นอาร์กิวเมนต์

ฟังก์ชัน Lambda มักจะถูกส่งโดยตรงไปยังฟังก์ชันที่มีลำดับสูงกว่า เช่น map หรือ filter

กำลังสองรายการตัวเลข

(map (lambda (x) (* x x)) '(1 2 3 4))  ; Returns (1 4 9 16)
  • ฟังก์ชัน lambda กำลังสองแต่ละองค์ประกอบของรายการ
  • ฟังก์ชัน map จะนำ lambda ไปใช้กับแต่ละองค์ประกอบ

ฟังก์ชัน Lambda เป็นค่าส่งคืน

คุณสามารถส่งคืนฟังก์ชัน lambda จากฟังก์ชันอื่นเพื่อสร้างพฤติกรรมแบบไดนามิกได้

การสร้างฟังก์ชัน Adder

(define (make-adder n)
  (lambda (x) (+ x n)))

(define add5 (make-adder 5))
(add5 10)  ; Returns 15
  • make-adder สร้างฟังก์ชัน lambda ใหม่ที่เพิ่มหมายเลขเฉพาะ (n)
  • แลมบ์ดาที่ส่งคืนจะถูกจัดเก็บไว้ใน add5 ซึ่งเพิ่ม 5 ในอินพุต

การใช้แลมบ์ดากับ let

Lambdas มักใช้กับ let เพื่อสร้างฟังก์ชันชั่วคราวที่มีขอบเขตในเครื่อง

Lambda ท้องถิ่นสำหรับการเพิ่มเติม

(let ((add (lambda (a b) (+ a b))))
  (add 3 4))  ; Returns 7
  • let เชื่อมโยงฟังก์ชัน lambda กับชื่อ add
  • จากนั้นแลมบ์ดาจะถูกใช้เป็นฟังก์ชันปกติภายในขอบเขต let

การรวม Lambdas เข้ากับฟังก์ชันลำดับที่สูงกว่า

Lambdas โดดเด่นเมื่อรวมกับฟังก์ชันที่มีลำดับสูงกว่าเพื่อทำการแปลงข้อมูลที่ซับซ้อน

การกรองเลขคู่

(filter (lambda (x) (= (modulo x 2) 0)) '(1 2 3 4 5 6))  ; Returns (2 4 6)
```- `lambda` ตรวจสอบว่าตัวเลขเป็นเลขคู่หรือไม่
- ฟังก์ชัน `filter` ใช้แลมบ์ดาเพื่อเก็บเฉพาะตัวเลขคู่จากรายการ

### ประโยชน์ของฟังก์ชันแลมบ์ดา

- **ความกระชับ:** Lambdas ลดโค้ดสำเร็จรูปโดยขจัดความจำเป็นในการกำหนดฟังก์ชันที่มีชื่อแยกต่างหาก
- **ความยืดหยุ่น:** คุณสามารถกำหนดและใช้งานได้ทุกที่ที่ต้องการ ทำให้โค้ดเป็นแบบโมดูลาร์มากขึ้น
- **ปรับปรุงให้อ่านง่ายขึ้น:** สำหรับงานเฉพาะเจาะจงสั้นๆ lambdas จะทำให้เจตนาชัดเจนโดยไม่ทำให้โค้ดยุ่งเหยิงด้วยฟังก์ชันที่มีชื่อเพิ่มเติม

### เมื่อใดจึงควรใช้ฟังก์ชัน Lambda

ใช้ฟังก์ชันแลมบ์ดาเมื่อ:

- ตรรกะนั้นสั้นและมีอยู่ในตัวเอง
- ฟังก์ชั่นนี้จำเป็นชั่วคราวหรือภายในขอบเขตเฉพาะเท่านั้น
- คุณกำลังทำงานกับฟังก์ชันที่มีลำดับสูงกว่า เช่น `map`, `filter` หรือ `reduce`

หลีกเลี่ยงการใช้ lambdas สำหรับตรรกะที่ซับซ้อนและมีหลายบรรทัด เนื่องจากจะทำให้อ่านง่ายน้อยลง สำหรับการดำเนินการที่ครอบคลุมมากขึ้น ให้ใช้ฟังก์ชันที่มีชื่อแทน

### บทสรุป

ฟังก์ชัน Lambda ใน Scheme มอบวิธีที่กระชับและมีประสิทธิภาพในการกำหนดฟังก์ชันที่ไม่ระบุตัวตนสำหรับงานเฉพาะ ความยืดหยุ่นและความสะดวกในการใช้งานทำให้เป็นเครื่องมือที่จำเป็นสำหรับโปรแกรมเมอร์ Scheme การทำความเข้าใจวิธีใช้ `lambda` อย่างมีประสิทธิภาพจะช่วยให้คุณเขียนสคริปต์ได้สะอาดตา เป็นโมดูลมากขึ้น และมีประสิทธิภาพ