13 May 2004

Functional Programming

เมื่อวานบังเอิญต้องใช้โปรแกรม bibtex2html เพื่อทำเพจของห้องแล็บ หลังจากโหลดซอร์สมา พอสั่ง ./configure ก็เกิดอาการอึ้งเล็กน้อย เพราะมันต้องการโปรแกรม ocamlc สำหรับคอมไพล์ เลยทำให้รู้จักภาษาคอมพิวเตอร์อีกภาษาหนึ่ง คือ ocaml ที่จริงไม่ใช่ภาษาหรอก เขาบอกว่า เป็นสำเนียงหนึ่งของภาษา ML (Meta Language) ซึ่งเป็น functional programming language (บังเอิญ คนเขียนโปรแกรมนี้ ทำวิจัยเกี่ยวกับ programming language อยู่ก็เลยใช้ภาษานี้ อย่างไรก็ดีโปรแกรมนี้ใช้งานได้ดีทีเดียว)

พอเห็นภาษา ocaml ก็เลยทำให้อยากรู้ว่ามันจะต่างจาก prolog ที่เราใช้อยู่ยังไง เลยลองอ่าน tutorial แล้วเลยลองเขียนฟังก์ชัน merge สำหรับ merge sort ดู (บังเอิญเขามีตัวอย่าง quick sort ให้ดู) ได้ฟังก์ชันออกมาอย่างข้างล่างนี้

let rec merge (x,y) = match (x,y) with
        ([],y) -> y
        | (x,[]) -> x
        | (x::xs, y::ys) when x>y -> x@(merge (xs,y::ys))
        | (x::xs, y::ys) -> y@(merge (ys,x::xs));;

ถ้าเทียบกับ prolog ดู จะค่อนข้างคล้ายกันมาก

merge(X,[],X).
merge([],X,X).
merge([X|Xs],[Y|Ys],[X|Zs]) :-
        X > Y, merge(Xs,[Y|Ys],Zs).
merge([X|Xs],[Y|Ys],[Y|Zs]) :-
        merge([X|Xs],Ys,Zs).

สิ่งแตกต่างที่พบคือภาษาตระกูล ML นี้ มองทุกอย่างเป็นฟังก์ชัน คือมีอินพุตแยกจากเอาท์พุต ส่วน prolog มองว่าเป็นเพียงความสัมพันธ์ระหว่างตัวแปรสามตัว ผมคิดว่าโดยทั่วไปแล้ว ocaml น่าจะทำความเข้าใจได้ง่ายกว่า เพราะมีการแบ่งแยกชัดเจน ในขณะที่ prolog ต้องดูเอาเอง ว่าต้องการให้อะไรเป็นสิ่งที่ใส่ลงไป แล้วอะไรเป็นสิ่งที่ต้องการ แต่ก็นั่นแหละ ocaml ก็คงสู้ prolog ไม่ได้ในเรื่อง unification เพราะพารามิเตอร์ของ predicate ทุกตัว ถือเป็นอินพุตได้หมด จะหาค่า X จาก merge(X,[3,2,1],[4,3,2,1]) ก็ทำได้ไม่แปลก ในขณะที่ ocaml ไม่ได้มีเป้าหมายเพื่อทำแบบนี้ ข้อดีอีกอย่างหนึ่งของ ocaml คือเรื่อง type เพราะต้องกำหนดให้แน่นอน (ขนาดบวก int กับ float ยังใช้เครื่องหมายแยกกันเลย) คงจะช่วยลดความซับซ้่อนไปได้เยอะ ในขณะที่ prolog ไม่เคยสนใจ type เลย ทำให้มั่วได้บ่อยมาก

No comments: