Functional Programming คืออะไร ? ทำไมมันถึงเป็นเรื่องที่น่าสนใจในยุคใหม่
By Arnon Puitrakul - 11 เมษายน 2026
ก่อนหน้านี้ไม่ค่อยได้สนใจการเอา Functional Programming มาใช้ในงานเท่าไหร่ แต่พอได้ลิ้มรสเท่านั้นแหละ มันเหมือนโลกใหม่มาก ๆ เข้ามาแก้ปัญหาหลาย ๆ อย่างที่เคยได้เจอมา วันนี้เราจะมาเล่ากันว่า มันคืออะไร และ มันน่าจะเหมาะกับงานไหนกัน
Functional Programming คืออะไร ?
Functional Programming (FP) เป็น Programming Paradigm ใหม่ที่ Software Engineer สมัยใหม่นำมาใช้เพื่อแก้ปัญหา Classic ของระบบขนาดใหญ่ โดยเฉพาะเรื่องของการจัดการ State และ Concurrency โดย Main Idea ของ FP คือ การมองโปรแกรมให้เหมือนการคำนวณสมการทางคณิตศาสตร์ เน้นการเขียน Function ที่ให้ผลลัพธ์ตายตัว (Pure Function) เลี่ยงการเปลี่ยนค่าตัวแปร (Immutability) และไม่สร้างผลกระทบกับส่วนใดส่วนหนึ่ง ส่งผลให้ Code ที่เราเดาผลลัพธ์ได้ง่าย เข้าใจได้ง่ายกว่า และทำ Testing ได้ง่ายกว่าเดิมมหาศาล
เมื่อพูดถึงความนิยม หากเราดูที่ปริมาณผู้ใช้งาน ภาษาในตระกูล Imperative หรือ OOP อย่าง Java, Javascript และ Python มันก็ยังเป็นภาษาที่ครองตลาดเป็นส่วนใหญ่อยู่ แต่หากเราเจาะลึกเข้าไปที่ FP เองที่อาจจะยังไม่ได้เป็น Mainstream แต่ การเติบโตในแง่ ความพึงพอใจของนักพัฒนาเอง และมูลค่าทางตลาดสูงขึ้นเรื่อย ๆ
ภาษาที่เกิดมาเป็น FP (Pure FP) หรือมีภาษาที่มีรากฐานมาจาก FP ทำคะแนนความพึงพอใจได้สูงมาก ๆ ในช่วงหลายปีที่ผ่านมา ตัวอย่างที่ชัดมาก ๆ คือ Rust ที่เป็นภาษาแบบ Multi-Paradigm ที่นำหลักการของ FP มาจัดการ Memory และจัดการ Concurrency อย่างเข้มข้น ครองอันดับ 1 ในฐานะภาษาที่นักพัฒนารักสุดติดต่อกันหลายปี นอกจากนี้ภาษาอย่าง Elixir, Clojure และ F# ก็มักจะเกาะอยู่ใน Top 10 ของภาษาที่มีคนอยากทำงานด้วยสุดเสมอ
ความสามารถในการเขียน FP น่าจะเป็นที่เพ่งเล็งในตลาดงานปัจจุบัน ผลสำรวจระบุอย่างต่อเนื่องว่าภาษาอย่าง Erlang, Elexir และ Clojure มักจะรั้งตำแหน่งกลุ่มฐานเงินเดินสูงอันดับต้น ๆ ซึ่งสะท้อนให้เห็นว่าบริษัทที่ทำสเกลใหญ่ยอมจ่ายแพงเพื่อแลกกับเสถียรภาพที่ FP มอบให้
ตัวชี้วัดความนิยทของ FP ที่ดีที่สุด อาจจะไม่ได้มาจากว่า คนหันมาใช้ภาษาที่เป็น Pure FP กัน แต่เป็นการที่ภาษา Mainstream เริ่มหยิบ Update ให้ตัวเองรองรับ FP ไม่ว่าจะเป็นพวกการนำ High-Order Function เข้ามาใน Javascript รวมถึงการมาถึงของ React Hooks, Pattern Matching ใน Python และ C# หรือแม้แต่ Records ใน Java ล้วนเป็นสิ่งที่พิสูจน์แล้วว่า แนวคิดแบบ FP เป็นที่ต้องการ และสามารถใช้งานได้จริงกับ Software Development ในปัจจุบัน
FP Core Ideas
ถ้าการเขียนแบบ OOP มองทุกอย่างเป็นวัตถุ ที่มี State และ Behaviour ของตัวเอง ฝั่ง Functional Programming ก็คือการมองการเขียนโปรแกรมทั้งหมดเป็น Pipeline ที่เราจะไม่มีการเก็บสถานะใด ๆ เอาไว้เลย ข้อมูลดิบแค่โดนโยนผ่าน Function และโดน Transform ไปเรื่อย ๆ จนได้ผลลัพธ์สุดท้ายที่ต้องการออกมา โดยมีกฏเหล็ก 4 ด้านที่เป็นเสาหลัก
อย่างแรกคือ Pure Function นี่คือ หัวใจที่สำคัญที่สุด จะต้องมี 2 คุณสมบัติย่อย ๆ คือ Deterministic คือ ถ้า Input เหมือนเดิม Output ออกมาต้องเหมือนเดิมเสมอ ไม่ว่าจะเรียกไปกี่รอบก็ตาม และอีกอย่างคือ No Side Effect คือ ห้ามมีการเปี่ยนแปลงค่าตัวแปรข้างนอก, ห้ามเขียนไฟล์ หรือแก้ไข Database ภายใน Function โดยตรง ไม่งั้นมันก็จะไปขัดกับส่วนแรกคือ เรียกกี่ทีมันจะไม่เหมือนเดิม
// Impure Function
let total = 0;
function addToTotal (amount) {
total += amount;
return total;
}
// Pure Function
function add (a,b) {
return a+b;
}จากตัวอย่างด้านบน เราพยายามทำให้เห็นว่า มันแตกต่างกันอย่างไร สาเหตุที่ Function ด้านบนเป็น Impure Function เพราะภายใน Function มีการเปลี่ยนแปลงค่าใน Global Variable และเรียกใช้มันอีก ทำให้ผลลัพธ์ในการเรียกแต่ละครั้งไม่เหมือนกันแน่นอน เช่น ครั้งแรก ใส่ 1 เราจะได้ 1 แต่รอบต่อไป เราใส่ 1 เหมือนเดิม มันกลับได้ 2 ก็จะขัดกับสิ่งที่เราบอกคือ No Side Effect และไม่ได้ตอบเรื่อง Deterministic เลย
อย่างที่ 2 คือ Immutability คือในโลกของ FP มันจะไม่มีการ Mutate หรือการแก้ไขข้อมูลเดิมเลย หากเราต้องการเปลี่ยนค่าอะไรสักอย่าง เราจะต้องสร้าง สำเนาตัวใหม่ ขึ้นมาแทนเสมอ การทำแบบนี้ ช่วยลบปัญหา Race Condition ในการทำ Concurrency ทิ้งไปได้เลย เพราะไม่มีใครมาแยกกันเขียนข้อมูลชุดเดียวกัน
// Mutable
const users = ['A','B'];
users.push('C');
// Immutable
const users = ['A', 'B'];
const updatedUser = [...users, 'C']จากตัวอย่างด้านบน เราจะเห็นว่า แบบแรกที่เป็น Mutable เราสร้าง Array ขึ้นมา บรรทัดต่อไป เรามีการ Push C เข้าไป นั่นแปลว่า หลังจาก Push ค่าใน Array นั้นก็จะมีการเปลี่ยนแปลงไปแล้ว แต่ในแบบด้านล่างที่เป็น Immutable แทนที่เราจะเพิ่มค่าเข้าไปตรง ๆ เราสร้าง Array ก้อนใหม่ออกมา เอาค่าจากตัวเดิมใส่เข้าไป แล้วค่อยเอาค่าใหม่เติมอัดทีหลัง
อย่างที่ 3 คือ Higher-Order Function คือใน Function มันจะไม่ใช่แค่ Block of Commands แล้ว แต่มันมีศักดิ์ และสิทธิ์ เทียบเท่ากับ ตัวแปรตัวหนึ่ง คือ เราสามารถจับ Function ยัดเข้าไปในตัวแปร ส่ง Function เป็น Parameter ของ Function อื่น หรือแม้แต่ Return ผลลัพธ์กลับไปเป็น Function ก็ยังได้
const numbers = [1,2,3,4];
const isEven = (num) => num % 2 === 0;
const evenNumbers = numbers.filter(isEven);ตัวอย่างด้านบน เห็นได้ชัด ๆ เลยว่า เราสร้างตัวแปร isEven ขึ้นมา แต่ไส้ใน มันไม่ใช่ค่าอะไรเลย มันกลายเป็น Function แทน และ Parameter ของ Filter Function เราก็สามารถยัด isEven ที่เป็น Function ใส่เป็น Parameter ได้ เห็นมั้ยว่า มันเป็นพลเมืองชั้น 1 แล้ว
อย่างที่ 4 คือ Declarative และ Imperative สั้น ๆ คือ เราจะคุ้นเคยกับการเขียนโปรแกรมแบบ Imperative หรือการสั่งแบบ Step-by-Step ไปเลยว่า วนลูปแบบนี้ สร้างตัวแปรนี้ บวกค่าแบบนี้ แต่การเขียนโปรแกรมแบบ FP เราใช้รูปแบบ Declarative คือ บอกไปเลยว่า เราต้องการอะไร ส่วนวิธีการทำงานปล่อยให้เบื้องหลังของภาษาเป็นตัวจัดการเอง
const numbers [1,2,3,4];
// Imperative
let sum = 0;
for (let i=0;i< numbers.length; i++) {
sum += numbers[i];
}
// Declarative
const total = numbers.reduce((acc, current) = acc + current, 0)ตัวอย่างด้านบน เราจะเห็นว่า ส่วนที่เป็น Imperative เราจะบอกทุกขั้นตอนหมดเลยว่า เราให้มันทำอะไร อย่างไรบ้าง แต่ส่วนที่เป็น Declarative เราไม่ได้บอกว่า Loop ยังไง แต่เราบอกแค่ว่า นายจะต้องเอาค่าบวกกันออกมาแค่นั้นเลย
อยากใช้ Functional Programming ตอนนี้มีตัวเลือกไหนบ้าง
ต้องเข้าใจกันก่อนนะว่า FP ไม่ใช่ภาษา แต่เป็น Paradigm ในปัจจุบัน มีการนำ Functional Programming เข้ามาใช้จริงใน Production แล้ว โดยแต่ละภาษาเขาจะมีการ Implement เข้ามาในระดับที่แตกต่างกัน
กลุ่มแรกคือ Pure Functional Language คือถูกออกแบบมาด้วยรากฐานของคณิตศาสตร์และ FP อย่างแท้จริง การเขียนในกลุ่มนี้ไม่มีคำว่า State Mutation ให้เห็นเลย เหมาะกับระบบที่ต้องการความเสถียรแบบสุดยอด ตัวอย่างเช่น Haskell ที่เป็นต้นตำหรับ และ Gold Standard ของ FP หากต้องการเข้าใจ Core Idea ของ Pure Function จริง ๆ นี่คือภาษาที่อยากให้ลองมาก ๆ แม้ใน Production จะหาคนเขียนยาก แต่เราว่าเป็นภาษาที่เรียนรู้ได้ดีที่สุด
Elixir เป็นอีกภาษาที่อยู่ใน Pure Function และเราคิดว่าเป็นตัวจริงในเรื่อง Concurrency แบบสุด มันสามารถรีดพลังจาก Multi-Core CPU ผ่าน Parallel Processing เพราะมันใช้ Actor Model ที่ทำให้สามารถรัน Process พร้อมกันเป็นล้าน ๆ ตัวโดยที่ระบบไม่พัง บริษัทอย่าง Discord และ Whatsapp ก็เลือกใช้เทคโนโลยีนี้เป็นหลักกันเลย และสุดท้ายคือ Clojure อยู่ในตระกูล Lisp ที่ทำงานอยู่บน JVM เก่งมาก ๆ เรื่องการจัดการ Immutable Data Structure เหมาะกับงานที่ต้องการประมวลผลข้อมูลที่ซับซ้อน
กล่มที่ 2 คือ Multi-Paradigm ที่มี FP แข็งแกร่งมาก ๆ กลุ่มนี้คือภาษาที่อนุญาติให้เขียนแบบ OOP หรือ Procedural ได้หมด แต่มี Feature ของ FP ระดับ First-class Citizen ให้ใช้ เป็นกลุ่มภาษาที่เราคิดว่าเป็นตัวเลือกแรก ๆ ของบริษัทในปัจจุบัน ตัวแรก หนีไม่พ้น Rust ก่อนเลย ที่หยิบไอเดีย FP มาแก้ปัญหาเรื่อง Memory Safety โดยไม่ต้องพึ่งพา Garbage Collector หรือ Feature อย่าง Pattern Matching, Algebraic Data Types และ Immutability be Default ทำให้ Rust เป็นภาษาที่ทรงพลังมาก ๆ เมื่อต้องการเขียนระบบที่ให้ Performance สูง และปลอดภัยสูงสุด
ถัดมาหนีไม่พ้น Scala ถือว่าเป็นเดอะแบกในวงการ Data Engineering ระบบการทำ Data Processing ตัวใหญ่ ๆ ระดับโลกอย่าง Apache Spark ก็ถูกเขียนด้วย Scala เพราะความสามารถในการทำ Data Transformation แบบ Function บน Distributed System และสุดท้ายผู้ท้าชิงจากฝั่ง .NET อย่าง F# นี่คือ Clean และจัดการกับ Module ที่ใส่ Business Logic ที่ซับซ้อนได้ดีมาก ๆ
และกลุ่มสุดท้ายคือ Mainstream Langugages ที่หยิบเอา Feature FP ไปใช้ อย่าง JavaScript/TypeScript เพราะการมาถึงของ React Hook และ Reux เป็นการเอา Concept ของ Immutability และ Pure Functions เข้ามา และมีการใช้ Array Method อย่าง map, filter และ reduce
อีกภาษาคือ Python, Java และ C# ภาษาฝั่ง Enterprise และ Data ที่เติบโตมาจาก OOP ก็ทยอยเพิ่ม Feature FP เข้ามาอย่างต่อเนื่องเช่น lambda และ List Comprehension บน Python, การใช้ Stream API บน Java และ LINQ และ Pattern Matching บน C# ที่ช่วยทำให้ Code สั้นลง และลดโอกาสการเกิด Bug ได้มหาศาล
Functional Programming เหมาะกับระบบแบบไหนดี ?
ถึงแม้ว่า Functional Programming จะมีข้อดีมากมาย แต่ในโลกของ Software Engineering ทุกเครื่องมือ ย่อมมีข้อดีข้อเสียที่ต้องแลกมาเสมอ การทำ FP มาใช้โดยไม่เข้าใจบริบทของการพัฒนา Software ของเราอาจจะสร้างปัญหามากกว่าการแก้ปัญหา
จากประสบการณ์ งานที่น่าจะเหมาะกับการเอา FP มาใช้ อย่างแรกคือ ระบบที่ต้องการ High Concurrency หรือกลุ่ม Distributed System เพราะปัญหาที่เราเจอกับระบบลักษณะนี้มานาน และยังไม่หายไปง่าย ๆ คือ Race Condition ที่ต่างคนต่างเขียนข้อมูลทับกันมั่วไปหมด ซึ่งก่อนหน้านี้ เรามีการเอากลไกเช่น Mutex และ Semaphore เข้ามาแก้ปัญหา แต่มันก็มีบางอย่างที่ต้องแลกมาเสมอ แต่ด้วยกฏ Immutability ของ FP มันเข้ามาแก้ปัญหานี้ให้หายไปทันที ทำให้สามารถ Scale ระบบ หรือทำ Parallel Processing ได้อย่างมั่นใจ และเราคิดว่านี่แหละคือสาเหตุที่ภาษาอย่าง Elixir หรือ Erlang มันถูกใช้เยอะมาก ๆ
อย่างถัดมา เป็นตัวที่เราใช้งานคือ Data Processing Pipeline หรือ ETL การเขียนโปรแกรมที่ต้องประมวลผลข้อมูลมหาศาล มันเหมือนเป็นการเอาข้อมูลดิบมาวิ่งผ่านท่อ และแปลงรูปทีละขั้นตอน ซึ่งมันเข้ากับสไตล์การเขียนแบบ Declarative ของ FP มาก ๆ ช่วยให้ Code ที่ออกมา อ่าน Flow ได้ง่าย และจัดการกับ Data Stream ได้อย่างมีประสิทธิภาพ
สุดท้ายระบบที่เหมาะมากคือ ระบบที่ต้องการ Testability และ Reliability สูงมาก ๆ เนื่องจากความ Pure Function ทำให้ไม่มี Side Effect เราสามารถเขียน Unit Test ได้ง่ายมาก ๆ ไม่ต้อง Mock Data หรือ Setup Process ให้วุ่นวายเลย แค่โยน Input และเช็ค Output ว่าตรงกับที่ควรจะเป็นหรือไม่
แต่งานที่ไม่เหมาะ หรือต้องระวังเลย เราว่า ก็มี 3 อย่างด้วยกัน อย่างแรกอันนี้ชัด ๆ คือ งานที่ต้องการ Performance หรือเล่นท่า Low-Level Hardware Optimisation เพราะการที่มันรองรับความ Immutability นั่นแปลว่า เวลาเราต้องการเปลี่ยนแปลงค่า เราต้องสร้างตัวแปรใหม่ทุกครั้ง นั่นมาพร้อมกับ Overhead ในการทำ Memory Allocation และ Garbage Collection สิ่งนี้ทำลาย Spatial Locality ของข้อมูลใน RAM ทำให้เกิด Cache Miss บน CPU Cache ได้ง่ายมาก ๆ ทำให้ถ้าเราต้องเขียน Software ที่ต้องรีด Performance ของ Hardware ออกมาจริง ๆ เช่นพวก Driver สำหรับควบคุมการทำงานของ ASIC หรือการจัดการข้อมูลระดับหน่วยความจำ คุยกับ NPU หรือ GPU การใช้ FP จะทำให้การเขียนโปรแกรมยากขึ้นแบบล้านเท่าได้เลย เพราะงานลักษณะนี้มันต้องอาศัยการทำ State Mutation และ Memory Allocation แบบ Manual จริง ๆ
อย่างที่ 2 คือ มันเป็นลักษณะการเขียนที่เราว่า มันต้องเปลี่ยนยันวิธีคิด และออกแบบ ถ้าเราคุ้นเคยกับการใช้ OOP มา ต้องมานั่งเขียน Class หรือการทำ Inheritance หรือการใช้ Design Patterns ฝั่ง OOP อาจจะต้องใช้เวลาปรับตัวค่อนข้างนาน ส่งผลกับ Team Agility อยู่พอสมควร
และสุดท้าย อันนี้คุยกับเพื่อนที่ทำ Game Engine บอกว่า มันเป็นงานที่ FP ไม่เคยอยู่ในตัวเลือกเลย เพราะมันเป็นลักษณะของโปรแกรมที่มี Entity เปลี่ยนเยอะมาก ๆ เช่นในฉากสักฉากมีตั้ง ตำแหน่งตัวละคร, HP และ Animation ต่าง ๆ ไปวิ่งไปพร้อมกันระดับ 60-120 FPS การพยายามสร้าง State ของเกมขึ้นมาใหม่ทุก ๆ Frame ตามหลัก FP อาจจะยังน้าาา เปลือง Resource มาก ๆ ทำให้แนวทางแบบ Imperative หรือ Data-Oriented Design น่าจะตอบโจทย์กว่ากันมาก ๆ
โลกเราอาจจะไปทาง Hybrid มากกว่า Pure FP
ตอนที่เราเรียนรู้ Functional Programming ใหม่ ๆ มันเกิดคำถามว่า มันจะเข้ามาแทนที่ OOP หรือ วิธีการเขียนโปรแกรมแบบเดิม ๆ ที่เราเคยเรียนรู้มามั้ย แต่พอได้เห็นโลกของการเขียนโปรแกรมมันเติบโตมาสักพัก เราว่า Programming Language สมัยใหม่ เขาเลิกคิดกันแล้วว่า การเขียนแบบนี้ดีกว่าอีกแบบ แต่มันคือการดึงจุดแข็งของแต่ละฝั่งมาใช้งานร่วมกัน ทำให้เราจะเห็นสถาปัตยกรรมที่ได้รับความนิยมใน Developer ที่ทำงานในสเกลใหญ่ ๆ คือ Functional Core, Imperative Shell
Imperative Shell คือ เขาจะใช้ OOP หรือ Procedual ในการจัดการกับ System Boundary เช่น การรับ HTTP Request, Database Connector, การจัดการ UI หรือกระทั่งการคุยกับ 3rd Party API เพราะโลกความจริงเต็มไปด้วย Side Effect นั่นหมายถึง State ที่เปลี่ยนแปลงตลอดเวลา
Functional Core คือ เมื่อดึงข้อมูลเข้ามาได้แล้ว เราจะส่งไม้ต่อไปให้ Core ที่เป็น Business Logic ที่เขียนด้วย Function Programming ล้วน ๆ ทำให้ส่วนที่ซับซ้อนที่สุดของ Application เราสามารถทำ Testing ได้ง่าย คาดเดาได้ง่าย และไร้ Race Condition ที่อาจจะเกิดขึ้นได้เลย
ตัวอย่างที่น่าสนใจ เราขอยกโลก Frontend อย่าง React + Redux เราจะเห็นว่า UI Component ทำหน้าที่เป็น Shell คอยรับ Event จาก User จากนั้นส่ง Action ไปให้ Reducer ซึ่งเป็น Pure Function ทำหน้าที่คำนวณและคืนค่า State ก้อนใหม่ขึ้นมา
สรุป : ทำไม Software Engineer ควรเข้าใจ FP ?
ต้องเข้าใจกันก่อนนะว่า Functional Programming ไม่ได้ทำได้ทุกอย่าง ไม่ได้เข้ามาแก้ปัญหาทุกอย่างของโลก Software Engineering และเราไม่เป็นต้องโยนชีวิตของการเขียน OOP มาเพื่อเขียน Functional เลย แต่เราว่าสิ่งที่เราจะได้เรียนรู้จากการศึกษาและลองมันคือ การเปลี่ยนวิธีคิดในการแก้ปัญหา
เมื่อเราเข้าใจ Pure Function เราจะเริ่มระวังเรื่องการสร้าง Side Effect ใน Codebase ของเราเอง หรือเมื่อเราเข้าใจ Immutability เราจะเลิกนสัยการ Reassign ค่าตัวแปรเดิม ๆ ซ้ำ ๆ ช่วยลด Bug แบบที่ เห้ย ตัวแปรนี้มันเปลี่ยนตอนไหนวะ ได้เยอะมาก ๆ
ท้ายที่สุดแล้ว ทักษะที่สำคัญของ Software Engineer มันไม่ได้อยู่ที่ว่า เราเขียนภาษานั้นเก่ง หรืออยู่กับ Paradigm ตัวนึง แต่การเข้าใจแก่นของมันจริง ๆ ทำให้เหมือนเรามีเครื่องมือหลากหลายอยู่ในกระเป๋า และรู้ว่า จังหวะไหนเราควรหยิบเครื่องมืออะไรออกมาใช้ต่างหาก ถ้ายังไม่เคยเขียน FP เลย อาจจะลองเริ่มใน Project เล็ก ๆ ด้วยการเขียน Pure Function 100% ดู บอกเลยว่า Code ที่เขียนออกมาจะดู Clean และเข้าใจง่ายขึ้นอย่างไม่น่าเชื่อ



