Functional programming part II
ชนิดข้อมูลลิสต์ และการประมวลผลลิสต์ แนวคิดเกี่ยวกับตัวแปรจะต่างจากแนวคิดเดิม Imperative: เชื่อมโยงชื่อตัวแปรกับตำแหน่งที่ใช้เก็บค่าในหน่วยความจำ ผู้ใช้สามารถเปลี่ยนแปลงค่าใน หน่วยความจำไปอย่างไรก็ได้ผ่านการสั่งกำหนดค่าตัวแปร Functional: จะเชื่อมโยงค่ากับตัวแปร โดยไม่มีการเกี่ยวข้องลงไปถึงตำแหน่งในหน่วยความจำ เช่น (define x 5) ; 5 เป็นชนิดข้อมูลพิ้นฐาน (primitive data types)
ชนิดข้อมูลลิสต์ และการประมวลผลลิสต์ ชนิดข้อมูลพื้นฐาน (ภาษาสคีม) อักขระ (characters) ข้อความ (strings) ค่าตรรกะ (Booleans) เลขจำนวนเต็ม (integers) จำนวนตรรกยะ (rational numbers) เลขจำนวนจริง (real numbers) เลขจำนวนเชิงซ้อน (complex number)
ชนิดข้อมูลลิสต์ และการประมวลผลลิสต์ (ต่อ) ชนิดข้อมูลคอมโพสิต (composite data type) มีเพียงประเภทเดียวคือ ลิสต์ (lists) Lists มีสมาชิกได้หลายจำนวน สมาชิกที่ปรากฏตัวแรกในลิสต์ เรียกว่า หัว (head) สมาชิกส่วนที่เหลือเรียกว่า หาง (tail) เช่น ‘(a b c) เป็นลิสต์ที่มีส่วนหัวคือ a และส่วนหางคือ ลิสต์ที่เหลือ ซึ่งได้แก่ ‘(b c) ลิสต์คือกลุ่มข้อมูลที่มีการเรียงลำดับตามตำแหน่งที่ปรากฏภายในลิสต์ จำนวนสมาชิกภายใน ลิสต์มีได้ตั้งแต่ศูนย์ตัวขึ้นไป ลิสต์ที่ไม่มีสมาชิกเลย เรียกว่า ลิสต์ว่าง (empty list, or null list) เขียนแทนด้วย () หรือ (nil) สมาชิกที่ปรากฏภายในลิสต์ สามารถเป็นค่าประเภทใดก็ได้ เช่น ค่าตรรกะ, ตัวเลข, ตัวแปร, สัญลักษณ์, อักขระ, ข้อความ , ลิสต์, ฟังก์ชัน …
ลิสต์ ตัวอย่าง (I like programming) (I (like) programs (with no objects)) ตัวอย่างแรกภายในลิสต์ประกอบด้วย symbol 4 ตัว ส่วนตัวอย่างที่สอง ภายในประกอบด้วย symbol 2 ตัว และลิสต์ 2 ตัว
ลิสต์ (ต่อ) ฟังก์ชันพื้นฐานที่ใช้ในการสร้างลิสต์ได้แก่ ฟังก์ชัน list และ quote ตัวอย่างเช่น ฟังก์ชันที่ประมวลผลด้วยลิสต์ประกอบด้วย (list 1 2 (+ 1 2)) ; has value (1 2 3) (quote (1 2 (+ 1 2))) ; has value (1 2 3) ‘(1 2 (+ 1 2)) ; has value (1 2 3) (null? X) (cons a x) (append x y) (car x) (cdr x) (length x) (reverse x)
นิพจน์ ผลลัพธ์ (define mylist (list 1 2 3 4 5)) Mylist (length mylist) (reverse mylist) (cons a mylist) (append ‘(a b) mylist) (null? mylist) (car mylist) (cdr mylist) (car (cdr mylist)) (cdr (cdr mylist)) (equal? ‘(1 2) ‘(1 2)) (equal? 5 5) (equal? ‘(1 2) ‘(2 1)) (equal? 5 ‘(5)) (equal? () ())
ฟังก์ชันเวียนบังเกิด (Recursive function) การสั่งทำงานซ้ำในการทำโปรแกรมเชิงหน้าที่จะใช้วิธี ให้ฟังก์ชันเรียกตัวเองซ้ำ หรือเรียกว่า ฟังก์ชันเวียนเกิด ลักษณะการเรียกตัวเองซ้ำ เมื่อมีการคำนวณค่า 4! เขียนแสดงขั้นตอนการทำงานได้ดังนี้ (define (factorial n)) (if (< n 1) 1 (* n (factorial (n - 1))))) (factorial 4)
Recursive Func. (cont) การสร้างฟังก์ชันเวียนเกิด จะเริ่มต้นด้วยการกำหนดกรณีพื้นฐาน (base case) ส่วนกรณีอื่นๆ ที่ไม่ใช่กรณี พื้นฐาน จะคำนวณค่าด้วยการเรียกตัวเองซ้ำ (recursive step) Most important, การเรียกตัวเองซ้ำนั้น จะต้องมีที่สิ้นสุด (define (sum alist) (if (null? alist) 0 (+ (car alist) (sum (cdr alist))))) (sum ‘(1 2 3 4))
Recursive Func. (cont) Recursive function เป็นวิธีสั่งทำงานที่มีรูปแบบสั้น แต่การใช้เนื้อที่ในหน่วยความจำจะ สิ้นเปลืองมาก เพราะต้องใช้เนื้อที่สแตกในแต่ละครั้งของการเรียกฟังก์ชัน Tail recursion ปรับให้ขั้นตอน recursion เกิดขึ้นท้ายสุด จะทำให้ใช้เนื้อที่สแตกน้อยลง ตัวอย่าง ให้นิยามฟังก์ชัน number-interval ที่ทำหน้าที่สร้างข้อมูลเป็นช่วง เช่นถ้าผู้ใช้ระบุ (number-interval 1 5 ) ผลลัพธ์ที่ได้จะเป็น (1 2 3 4 5)
Recursive and tail-recursive functions (define (number-interval f t) (if (> f t) ‘() (cons f (number-interval (+ f 1) t)) )) Tail-recursive function (define (number-interval-tail f t) (reverse (number-interval-help f t ‘()))) (define (number-interval-help f t result) (if (> f t) result (number-interval-help (+ f 1) t (cons f result)) ))
ฟังก์ชันอันดับสูง (Higher-order function) ความสามารถที่สำคัญที่สุดของ Functional programming คือ การนิยาม และการใช้ฟังก์ชันอันดับสูง ฟังก์ชันนั้นจะถูกจัดว่าเป็นฟังก์ชันอันดับสูง ถ้าฟังก์ชันนั้น สามารถรับฟังก์ชันอื่นเป็นพารามิเตอร์ และสามารถส่งกลับ ค่าเป็นฟังก์ชัน ฟังก์ชัน flip รับพารามิเตอร์ f ซึ่งเป็นฟังก์ชันมีสองพารามิเตอร์คือ x และ y จากนั้น flip ทำคำสั่ง (f y x) ซึ่งเป็นการส่งค่ากลับเป็นฟังก์ชัน f ที่มีพารามิเตอร์ตัวแรกเป็น y และตัวที่สองเป็น x ดังนั้น flip จึงเป็นฟังก์ชันอันดับสูงที่ทำหน้าที่รับฟังก์ชันสองพารามิเตอร์ แล้วส่งฟังก์ชันกลับโดยสลับลำดับของ พารามิเตอร์ รูปแบบเต็มของฟังก์ชัน (define flip (lambda (f) (lambda (x y) (f y x)))) รูปแบบย่อของฟังก์ชัน (define (flip f) (lambda (x y) (f y x))))
Higher-order function (cont) ภาษาสคีมมักจะมีการใช้ฟังก์ชัน map เป็นฟังก์ชันอันดับสูง รับพารามิเตอร์เป็นฟังก์ชัน และใช้ฟังก์ชันนั้นบนข้อมูล ทุกตัวในลิสต์ ฟังก์ชัน map สามารถนิยามได้ดังนี้ (map square’(1 2 3 4 5)) ; (map string? List 1 ‘en “en” 2 ‘to “to”)) ; (map (lambda (x) (* 2 x)) (list 10 20 30 40)) ; (define (map f x) (cond ((null? x) ‘()) (else (cons (f (car x)) (map f (cdr x))))))
Higher-order function (cont) (filter even? ‘(1 2 3 4 5)) (define (filter predicate alist) (reverse (filter-help predicate alist ‘() ))) (define (filter-help predicate alist result) (cond ((null? alist) result) ((predicate (car alist)) (filter-help predicate (cdr alist) (cons (car alist) result))) (else (filter-help predicate (cdr alist) result)) ))