- นักพัฒนาที่ให้ความสำคัญกับ การเขียนโปรแกรมเชิงฟังก์ชันและการรับประกันแบบสแตติก หลังจากได้ลองใช้หลายภาษาแล้ว มองว่า OCaml เป็นภาษาที่มีการออกแบบสมดุลอย่างมาก
- เมื่อเทียบกับ ระบบชนิดข้อมูลที่ซับซ้อนและความเร็วคอมไพล์ที่ช้า ของ Haskell แล้ว OCaml มอบทั้งความเรียบง่ายและการใช้งานจริง
- มีความคล้ายกับ Go ในด้าน การคอมไพล์ที่รวดเร็วและรันไทม์ที่กระชับ แต่ยังคงจุดแข็งของภาษาฟังก์ชันอย่าง pattern matching และ sum type เอาไว้
- มี การบิลด์ที่รวดเร็ว, ไบนารีแบบสแตติก, เครื่องมือเอกสารที่ครบถ้วน (odig, utop) ช่วยเพิ่มทั้งประสิทธิภาพการทำงานและการเข้าถึง
- ความสมดุล ระหว่างความเรียบง่ายกับพลังในการแสดงออก รวมถึงการออกแบบภาษาที่ประณีต ถูกยกให้เป็นเสน่ห์ที่สำคัญที่สุดของ OCaml
ประสบการณ์และการเปรียบเทียบภาษาโปรแกรม
- จากประสบการณ์พัฒนาซอฟต์แวร์ทั้งแบบสมัครเล่นและระดับมืออาชีพด้วยหลายภาษา ผู้เขียนได้สรุป คุณลักษณะของภาษาที่ดี ไว้ดังนี้
- ให้ความสำคัญกับความเร็วในการคอมไพล์, รันไทม์ที่เรียบง่าย, การรับประกันแบบสแตติกที่แข็งแรง, องค์ประกอบเชิงฟังก์ชัน, ประสิทธิภาพที่ดี และคุณภาพของเอกสาร
- Haskell ช่วยให้เข้าใจแนวคิดของการเขียนโปรแกรมเชิงฟังก์ชัน แต่ถูกชี้ว่ามีปัญหาเรื่อง ไวยากรณ์ที่ซับซ้อนและการคอมไพล์ที่ช้า
- แนวโน้มของชุมชนที่ มุ่งไปสู่ความซับซ้อน และปัญหารันไทม์อย่าง space leak ทำให้การบำรุงรักษาทำได้ยาก
- Go ทำให้ได้ทั้งความเรียบง่าย การคอมไพล์ที่รวดเร็ว ระบบเครื่องมือที่ดี และโค้ดที่เข้าใจได้ง่าย
- แต่ก็มีข้อจำกัดจาก การออกแบบที่ค่อนข้างอนุรักษนิยม, การจัดการข้อผิดพลาดที่ยืดยาว, และ การไม่มีการตรวจ null แบบชัดเจน ทำให้เกิดบั๊กได้ง่ายและใช้งานไม่สะดวก
- การไม่มี REPL และท่าทีเชิงลบต่อแนวคิดเชิงฟังก์ชันก็ถูกกล่าวถึงว่าเป็นข้อจำกัดเช่นกัน
จุดแข็งสำคัญของ OCaml
- OCaml ถูกประเมินว่าเป็นภาษาที่ตอบโจทย์เกณฑ์ข้างต้นได้เกือบทั้งหมด
- การรับประกันแบบสแตติกที่แข็งแรง: รองรับ sum type, polymorphic variant, pattern matching
- รันไทม์ที่เรียบง่าย: ใช้ garbage collection แต่ยังทำงานได้ในระดับภาษาระบบ
- ความเร็วในการคอมไพล์สูง: ผ่านระบบบิลด์ Dune ซึ่งเร็วกว่า Haskell หรือ Rust
- สร้าง ไบนารีเดี่ยวแบบ static link ได้ จึงสะดวกต่อการดีพลอย
- เครื่องมือเอกสารที่ยอดเยี่ยม: odig (สำรวจเอกสารแบบออฟไลน์), utop (REPL), และโครงสร้างที่แยกไฟล์ interface กับ implementation ออกจากกัน
- ฟีเจอร์ การอนุมานชนิดข้อมูลอัตโนมัติ ช่วยเพิ่มประสิทธิภาพในการเขียนโค้ด
- โครงสร้างที่กำหนดชนิดข้อมูลไว้ในไฟล์ interface ช่วยให้การสำรวจโค้ดทำได้ชัดเจนยิ่งขึ้น
การออกแบบภาษาและความประทับใจ
- แม้ OCaml จะเป็นภาษาที่มีอายุมากแล้ว แต่ก็ยังคงมี ความรู้สึกของการออกแบบที่ประณีต
- ฟีเจอร์เชิง วัตถุ บางส่วนหรือไลบรารีที่ซับซ้อนบางตัว ถูกมองว่าไม่จำเป็น
- โดยรวมแล้ว ความสมดุลระหว่างความเรียบง่ายกับพลังในการแสดงออก รวมถึง เอกสารและระบบเครื่องมือที่ดี คือเสน่ห์หลักของ OCaml
- ผู้เขียนชื่นชม OCaml อย่างมากในฐานะ “ภาษาที่เรียบง่ายแต่แสดงออกได้ทรงพลัง” และกล่าวว่ามันมอบความพึงพอใจที่หาได้ยากจากภาษาอื่น
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
เคยลองใช้ OCaml อยู่บ้างและเจอปัญหาหลายอย่าง
การรองรับ Windows แย่มาก เพิ่งดีขึ้นมาเป็นระดับ “แย่น้อยลงพอสมควร” ตอนมาถึง OCaml 5
ไวยากรณ์อ่านยากสำหรับมนุษย์ และพอเกิด syntax error แค่พิมพ์ผิดไปตัวเดียวก็อาจได้ error ยาว 1000 บรรทัด
Ocamlfmt ชอบบีบแม้แต่
matchที่ซับซ้อนให้เหลือบรรทัดเดียว ทำให้อ่านยากเอกสารก็กระชับเกินไปและแทบไม่มีตัวอย่าง
OPAM ดูดีในทางทฤษฎี แต่ของจริงมีบั๊กเยอะ ถึงขั้นเคยมีบั๊กที่ถ้าอยู่ใน Unix group เกิน 32 กลุ่มจะหา
curlไม่เจอtype annotation ของ function signature เป็นทางเลือก ทำให้ข้อดีของ static typing ลดลง
ecosystem ก็เล็ก แถมไม่มีแม้แต่ฟังก์ชันในตัวสำหรับคัดลอกไฟล์
การยึดติดกับ singly linked list ก็ไม่มีประสิทธิภาพ
ถึงอย่างนั้นก็ยังดีกว่า C หรือ Python แต่คงไม่เลือกมันแทน Rust
เพราะ target ไปที่ CLR การ deploy จึงง่ายกว่ามาก และใช้ ecosystem ของ .NET ได้ตรง ๆ
ใช้ไลบรารี NuGet สำหรับ C# หรือ VB.NET ได้แทบจะตรงตัว ทำให้ ecosystem ใหญ่มาก
เอกสารของ F# ก็มีมากกว่าและมีตัวอย่างเยอะกว่าเยอะ
ลิงก์อ้างอิง: F# Language Reference, F# Core Docs, F# Cheatsheet
curlของ OPAM มีจริงไหม ก็เจอใน issue #5373ที่จริงแล้วเป็นปัญหาเกี่ยวกับ musl และเกิดจาก OPAM ถูก build ด้วยไบนารีนั้น
ocamlformatถ้าตั้งเป็น janestreet profile จะดีกว่าค่าเริ่มต้นมากปัญหา type annotation ของ function signature แก้ได้ถ้ามีไฟล์
.mliให้ แต่ส่วนใหญ่ไม่ค่อยทำกันแทนที่จะเป็นอย่างนั้น ปลั๊กอิน OCaml สำหรับ VS Code กลับให้ประสบการณ์ที่ดีที่สุดสำหรับมือใหม่
บนฮาร์ดแวร์สมัยนี้ collection พื้นฐานน่าจะเป็น vector มากกว่าไหม
เมื่อก่อนถึงขั้นติดตั้งตรงจาก ocaml.org ยังไม่ได้ ต้องผ่าน mingw หรือ wsl
เลยแทบจะเรียกได้ว่าไม่มี OCaml สำหรับ Windows จริง ๆ
เหตุผลที่ผู้ออกแบบภาษา Go แทบไม่รับเอาแนวคิดจาก functional programming มาเลยนั้นชัดเจน
อย่างที่ Rob Pike พูด นักพัฒนาของ Google ส่วนใหญ่ยังหนุ่มและคุ้นกับภาษาในตระกูล C จึงต้องการ ภาษาที่เรียนรู้ง่าย
เพราะการเปลี่ยนวิธีคิดไปสู่ภาษาสาย functional ต้องใช้เวลามาก Go จึงพยายามหลีกเลี่ยงต้นทุนนั้น
ทุกครั้งที่เห็นคำว่า “ML” ใจยังเต้นแรงอยู่พักหนึ่ง ก่อนจะนึกได้ว่ามันไม่ใช่ Meta Language แต่เป็น Machine Learning แล้วก็ผิดหวัง
ทุกวันนี้ยิ่งไม่ชอบที่คำว่า “AI” ถูกใช้พร่ำเพรื่อ
อยากให้เลิกใช้คำว่า AI ไปเลยจนกว่าจะมี AGI ของจริง
ถ้าดูบรรยายของ Richard Feldman จะอธิบายได้ดีว่าทำไมภาษา functional ถึงไม่กลายเป็นกระแสหลัก
ต้องเป็นภาษาที่ผูกขาดโดยแพลตฟอร์ม หรือมี killer app หรือมีงบการตลาดมหาศาล
ที่ Python โตเร็วก็เพราะมันกลายเป็น ภาษาศูนย์กลางของ ecosystem AI
ผมเองก็เรียน functional ด้วย OCaml และทำโปรเจกต์ด้วย Haskell กับ Zig แต่สุดท้ายก็กลับมาสู่ความจริงว่า “ใช้เครื่องมือที่ใช้งานได้จริง”
OCaml, Rust, Haskell เป็นภาษายอดนิยมในแง่ “ภาษาที่คนอยากเรียน” แต่ไม่ใช่ “ภาษาที่ถูกใช้แพร่หลายจริง”
Torch เดิมทีสร้างบน Lua แล้วค่อยย้ายมาที่ Python ซึ่งตอนนั้นดังอยู่แล้ว
ฝั่ง FP ไม่ค่อยสนใจการเปลี่ยนแปลงทางเทคโนโลยีในโลกจริง ระหว่างนั้นภาษาอย่าง C, Pascal, Perl, Tcl ก็ยึดตลาดไป
สุดท้าย FP เลยกลายเป็น “นักบวชในมหาวิหาร” ส่วนภาษาสาย imperative ได้มวลชนไป
เคยใช้ F# แล้วรู้สึกว่า concurrency แบบ Actor เข้าใจง่ายดี
แต่พอมี mutable Array เข้ามาก็เริ่มซับซ้อน
เลยสงสัยว่ามีเหตุผลอะไรให้เลือก OCaml มากกว่า F# ในงานจริง
ส่วน OCaml มี การเอา global lock ออก, compile เร็ว และมีความสามารถทรงพลังอย่าง module, GADT, effect
F# ยังเหนือกว่าในเรื่องการรองรับ Windows, SIMD และ unboxed type แต่ OCaml ก็กำลังไล่ตามมาเรื่อย ๆ
ไลบรารีมีเยอะก็จริง แต่ส่วนใหญ่ ไม่ค่อยเป็น F# เท่าไร
OCaml มี native ecosystem ที่ใหญ่กว่า
การทำงานร่วมกับ C# ดีมากก็จริง แต่ การใช้ไลบรารี F# จาก C# นั้นเหมือนฝันร้าย
สุดท้ายก็ต้องคง shell ของ C# ไว้ ทำให้ codebase กลายเป็นลูกผสม
ecosystem ของ .NET อุดมสมบูรณ์ แต่ แนวคิดแบบ OOP ฝังแน่นและชนกับสไตล์ FP
Visual Studio สะดวกก็จริง แต่ไม่เข้ากับ workflow แบบ CLI
ความเร็วในการ compile ก็ช้าลงเรื่อย ๆ และการทดสอบก็ดูขัด ๆ
พอลองใช้ OCaml แล้วรู้สึกว่าการออกแบบด้าน สรีรศาสตร์ของภาษา เป็นธรรมชาติกว่ามาก
F# มักถูกเรียกว่า “OCaml for .NET” แต่จริง ๆ แล้วมันเป็นเพียง ภาษาในสาย ML และแทบจะเป็นคนละภาษากัน
OCaml เป็นภาษาเก่าแก่ก็จริง เลยคิดว่าฟีเจอร์ OOP ตัดออกไปก็ได้ แต่ผมมองว่า Standard ML สมบูรณ์กว่า
มันมีประโยชน์กับ record แบบ structural type, open recursion, และ JS binding อย่าง
Js_of_ocamlแถมยังไม่รองรับ record update เลยใช้งานไม่สะดวก
ตั้งแต่ต้นยุค 2000 OCaml เป็นภาษาแบบ “เกือบสมบูรณ์แบบ” มาโดยตลอด
แต่พอถึงเวลาที่ จุดเสียดทาน ต่าง ๆ ถูกแก้ ภาษาอื่นก็รับเอาไอเดียเหล่านั้นไปใช้กันหมดแล้ว
คนเรียนมีไม่มาก แต่ใครที่เรียนแล้วก็มักไปสร้างภาษาใหม่
ที่มา
ตอนนี้ก็มีหลายโปรเจกต์ที่รันด้วย OCaml ได้ดีอยู่แล้ว
แถมยังเพิ่ม effect system เข้ามาอีก ทำให้ยิ่งล้ำหน้าไปกว่าเดิม
ความนิยมกับความเก่งเป็นคนละเรื่อง
ความนิยม ≠ ความยอดเยี่ยม ดนตรีก็เหมือนกัน
มันขึ้นกับกระแสและแรงเฉื่อยเท่านั้น
ยิ่งภาษาไหนมีคนใช้มาก ก็ยิ่งมีคนไม่ชอบมาก
ส่วนภาษาที่ไม่คุ้นเคยมักถูกประเมินค่าสูงเกินจริงได้ง่าย
ที่ OCaml ไม่ค่อยนิยมก็เพราะ กลุ่มผู้ใช้ที่สัมผัสประสิทธิภาพนั้นมีขนาดเล็ก
และท่าทีแบบ ยึดหลักคำสอน ของฝั่ง FP ก็มีส่วนด้วย
คิดว่า Elixir เป็นภาษาที่คล้าย OCaml แต่มีโอกาสไปสู่กระแสหลักมากกว่า
มันมีข้อดีของ FP อย่าง immutability, pattern matching, Actor model
และทำงานได้เสถียรบน BEAM runtime
แม้ยังไม่มี static typing แต่ก็กำลังเพิ่มการตรวจ type แบบค่อยเป็นค่อยไป
ทั้งที่ใช้ ecosystem ของ .NET ได้ตรง ๆ แต่กลับเป็นที่รู้จักน้อยกว่า OCaml
มีหลายบริษัทที่ใช้มันทำ SaaS backend จริง
เพราะงั้นภาษา FP ก็ยังคงอยู่นอกกระแสหลัก
OCaml คล้าย Go ตรงที่เป็น ภาษา systems ที่ใช้ GC
ผมชอบ GC มากกว่าการจัดการหน่วยความจำเองหรือ borrow checking
GC ของภาษา D ก็ยอดเยี่ยมเหมือนกัน แต่ปัญหาคือคำว่า “GC” เองนี่แหละที่ทำให้คนกลัว