OxCaml - ชุดส่วนขยายสำหรับภาษาโปรแกรม OCaml
(oxcaml.org)- OxCaml คือ ชุดส่วนขยายที่เพิ่มความสามารถด้านประสิทธิภาพให้กับ OCaml
- เป็นทั้ง คอมไพเลอร์สำหรับงานโปรดักชันของ Jane Street และ สนามทดลองสำหรับฟีเจอร์อนาคตของ OCaml
- มุ่งขยายการควบคุมประสิทธิภาพโดยให้ความสำคัญกับ ความปลอดภัย ความสะดวก และความคาดการณ์ได้
- มีฟีเจอร์ครอบคลุมหลายด้าน เช่น Fearless concurrency, การควบคุมเลย์เอาต์, การควบคุมการจัดสรรหน่วยความจำ
- เปิดเป็นโอเพนซอร์สเพื่อให้ ผู้ใช้สายทดลองและนักวิจัย ทดสอบและให้ข้อเสนอแนะได้อย่างอิสระ
แนะนำ OxCaml
OxCaml คืออะไร
- OxCaml คือ ชุดส่วนขยายที่พัฒนาอย่างรวดเร็วสำหรับภาษาโปรแกรม OCaml
- มันเป็นทั้ง คอมไพเลอร์สำหรับใช้งานจริงของ Jane Street และ แพลตฟอร์มเชิงทดลองเพื่อเสริมการเขียนโปรแกรมที่เน้นประสิทธิภาพของ OCaml
- เป้าหมายคือ ผลักดันส่วนขยายเหล่านี้กลับเข้าสู่ OCaml อย่างเป็นทางการในระยะยาว
เป้าหมายการออกแบบหลักของ OxCaml
- มีเป้าหมายเพื่อมอบสภาพแวดล้อมที่สามารถควบคุม ปัจจัยด้านประสิทธิภาพที่กำหนดพฤติกรรมของโปรแกรม ได้อย่างปลอดภัย สะดวก และคาดการณ์ได้
- การควบคุมนี้จะ เปิดให้ใช้แบบเลือกเฉพาะเมื่อจำเป็นจริงเท่านั้น
- ทุกอย่างถูก ทำงานและใช้งานภายในสภาพแวดล้อมของ OCaml
แนวทางการออกแบบที่เป็นรูปธรรม
-
ความปลอดภัย: เสริมความปลอดภัยในระดับภาษาเพื่อคงไว้ซึ่งประสิทธิภาพการทำงานของโปรแกรมเมอร์และความถูกต้องของโค้ด ภาษาที่ไม่ปลอดภัยในวงกว้างมักใช้งานได้ยาก
-
ความสะดวก: เพิ่มอำนาจในการควบคุมโดยไม่เพิ่มความซับซ้อนของการเขียนโปรแกรม และยังคงข้อดีของการอนุมานชนิดข้อมูลไว้
-
ความคาดการณ์ได้: ทำให้คุณลักษณะด้านประสิทธิภาพหลัก ปรากฏอย่างชัดเจนในระดับระบบชนิดข้อมูล เพื่อให้วิเคราะห์ประสิทธิภาพของโค้ดได้ง่ายขึ้น
-
ส่วนขยายเหล่านี้ใช้แนวทาง pay-as-you-go ที่ใช้เฉพาะส่วนที่จำเป็น กล่าวคือ หากไม่ใช้ฟีเจอร์ส่วนขยาย ก็ยังคงความเรียบง่ายและรูปแบบเดิมของ OCaml เอาไว้ได้
-
OxCaml เข้ากันได้กับทุกโปรแกรม OCaml และภายในมุ่งสู่การเป็น OCaml ที่วิวัฒน์ต่อไป โดยยังคง ความปลอดภัย ความง่ายในการใช้งาน และประสิทธิภาพการพัฒนา แบบเดิมของ OCaml
แนะนำฟีเจอร์ส่วนขยายของ OxCaml
Fearless concurrency
- เพื่อแก้ปัญหาที่ว่า การเขียนโปรแกรมแบบคอนเคอร์เรนซี ให้ถูกต้องนั้นทำได้ยากมาก OxCaml จึงใช้การขยายระบบชนิดข้อมูลเพื่อ ป้องกัน data race แบบสแตติก
เลย์เอาต์ (Layouts)
- โปรแกรมเมอร์สามารถกำหนดเลย์เอาต์ข้อมูลในหน่วยความจำได้อย่างชัดเจน
- ยังรองรับ การเข้าถึงแบบเนทีฟสำหรับส่วนขยายตัวประมวลผล SIMD บนฮาร์ดแวร์สมัยใหม่ด้วย
การควบคุมการจัดสรรหน่วยความจำ
- มี เครื่องมือสำหรับควบคุมการจัดสรรหน่วยความจำอย่างละเอียด เพื่อลดภาระของ garbage collection (GC) และ เพิ่มประสิทธิภาพแคชรวมถึงความเป็นเชิงกำหนดของโปรแกรม
การปรับปรุงคุณภาพการใช้งาน (Quality of life)
-
นอกจากงานเขียนโปรแกรมระบบแล้ว ยังมีฟีเจอร์ที่ช่วยงานเฉพาะด้านต่าง ๆ ได้ด้วย
- Polymorphic parameters
- Include functor
- Labeled tuples
- Immutable arrays
การใช้งานและการนำ OxCaml ไปใช้
-
OxCaml เปิดเป็นโอเพนซอร์ส ทำให้ นักวิจัย ผู้ใช้สายทดลอง และนักพัฒนา สามารถมีส่วนร่วมผ่านการทดสอบและการให้ข้อเสนอแนะได้
-
อย่างไรก็ตาม ฟีเจอร์ส่วนขยายของ OxCaml ไม่ได้รับประกันเสถียรภาพและความเข้ากันได้ย้อนหลัง (แต่ยังรับประกันความเข้ากันได้ย้อนหลังกับโปรแกรม OCaml เดิม)
-
มีการจัดเตรียม เวอร์ชันของเครื่องมือมาตรฐาน OCaml ที่ปรับให้เข้ากับ OxCaml
- การจัดการแพ็กเกจ: ใช้งานร่วมกับ dune และ opam ได้
- การรวมเข้ากับเอดิเตอร์: รองรับ LSP-server
- มีฟังก์ชันจัดรูปแบบซอร์สโค้ดและสร้างเอกสาร
-
ไลบรารีและเครื่องมือต่าง ๆ ที่ Jane Street เผยแพร่ มีให้ใช้งานสองรูปแบบ
- สำหรับ Upstream OCaml: เวอร์ชันที่ตัดส่วนขยายของ OxCaml ออก
- สำหรับ OxCaml โดยเฉพาะ: เวอร์ชันที่ใช้ประโยชน์จากฟีเจอร์ส่วนขยาย
-
ส่วนขยายบางอย่างไม่สามารถถอดออกได้ ทำให้ไลบรารีเหล่านั้น ใช้งานได้เฉพาะบน OxCaml เท่านั้น และหากส่วนขยายที่จำเป็นถูกรวมเข้า OCaml อย่างเป็นทางการแล้ว ก็มีแผนจะเผยแพร่ เวอร์ชันที่เข้ากันได้กับ OCaml ด้วย
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
อยากแนะนำว่ามีพอดแคสต์ตอนหนึ่งที่มีคนจากทีม Janet Street มาร่วมรายการ ซึ่งมีการพูดคุยที่น่าสนใจเกี่ยวกับประเด็นด้านประสิทธิภาพเวลาใช้งาน OCaml
ยังมีความกังวลต่อเนื่องเกี่ยวกับการนำภาษา GC ไปใช้ในสภาพแวดล้อมที่ต้องการ latency ต่ำมาก
ตัวอย่างเช่น ถ้าเกิด GC pause ขึ้นระหว่างการเทรดความถี่สูง ก็อาจกลายเป็นปัญหาร้ายแรงได้
แชร์ ลิงก์พอดแคสต์
เคยมีประสบการณ์ถาม Ron Minsky ตรง ๆ บน Twitter ว่าทำไมไม่ใช้ Rust สำหรับแอปพลิเคชัน latency ต่ำ
คำตอบของ Ron ยอมรับว่า Rust ยอดเยี่ยม แต่เน้นไปที่คุณค่าของการคงโค้ดทั้งหมดไว้ในภาษาเดียว
ทั้ง type, tool, library, idiom ต่าง ๆ สามารถใช้ร่วมกันได้ และย้ายข้ามโปรเจ็กต์ได้ง่ายมาก
อีกทั้งภายใน OCaml เองก็กำลังพัฒนาให้ผสานข้อดีหลักของ Rust ได้ดี เพื่อให้ค่อย ๆ นำมาใช้ได้
ข้อเสียของ Rust ที่กล่าวถึงคือเวลา compile ที่นาน ระบบ type ที่ซับซ้อน และความไม่พอใจต่อการจัดการ async/await
เหนือสิ่งอื่นใดคือการย้ำจุดยืนว่าต้องการเครื่องมือภาษาเดียวที่เหมาะกับสภาพแวดล้อมการทำงานที่กว้างขวาง
ลิงก์ทวีตดังกล่าว
เน้นว่าปัญหาหลักไม่ใช่ภาษา GC เอง แต่เป็นมุมมองที่เหมารวมทุกภาษา GC เป็นแบบเดียวกัน
ปัญหาที่สำคัญจริง ๆ คือเมื่อภาษา GC ไม่รองรับการจัดการ stack และ value type อย่างชัดเจน
ถ้าต้องการทั้ง productivity ของภาษา GC และตัวเลือกที่ละเอียดพอสำหรับการเขียนโค้ดระดับระบบ ก็มีทางเลือกอย่าง Cedar, ตระกูล Oberon, Modula-3, D, Nim, Eiffel, C#, F#, Swift, Go
พูดในภาพรวมของ runtime ที่ใช้ GC ว่าสามารถใช้สิ่งอย่างอัลกอริทึมเก็บกวาดแบบขนานของ JVM เพื่อลด GC pause ได้
แต่แนวทางนี้ไม่ได้ให้การรับประกันแบบตายตัว จึงทำให้เกิดสถานการณ์ที่ต้อง overprovision RAM ของระบบเพิ่ม
ถัดจากนั้นยังมีวิธี overprovision เซิร์ฟเวอร์โดยตั้งใจ เพื่อให้บางเครื่องหลุดออกจาก pool ชั่วคราวและทำ "offline GC" ได้
วิธีลักษณะนี้ต้องอาศัยความร่วมมือระหว่าง request router กับเซิร์ฟเวอร์ จึงมีความหมายก็ต่อเมื่อมีงบพอสำหรับขยายจำนวนเซิร์ฟเวอร์
คำอธิบาย Parallel GC ของ JVM
แชร์ประสบการณ์ว่าหลายระบบเคยลำบากกับปัญหา GC compaction
ในระบบเทรดมักใช้แนวทางว่าหลังจากเริ่มทำงานแล้วจะพยายามลดการ allocation ให้เหลือน้อยที่สุด
ฝั่ง JS มีไลบรารีชื่อ "Zero" ที่ให้ยูทิลิตีแบบไม่ต้อง allocation
แม้จะยังไม่ได้กดดูที่ลิงก์ แต่มีความเห็นว่าถ้าเป็นสภาพแวดล้อมอย่างการเทรดที่มีช่วงเปิด-ปิดตลาด ก็อาจใช้วิธีปิด GC ระหว่างเวลาตลาดเปิด แล้วค่อยรีสตาร์ตหลังตลาดปิดได้
อยากเน้นว่าฟีเจอร์แรกจาก fork นี้ที่ถูก upstream เข้าไปคือ labeled tuple
มีกำหนดรองรับใน OCaml 5.4
ลิงก์ PR ที่ upstream
ลิงก์การพูดคุยที่เกี่ยวข้อง
ถึงฟีเจอร์นี้จะดูเล็กน้อย แต่ก็ค่อนข้างน่าตื่นเต้น
อยากเพิ่มข้อมูลว่าผู้เขียนฟีเจอร์นี้มีทั้งบทความวิจัยและวิดีโอที่นำเสนอใน ML2024
วิดีโอ Youtube
PDF บทความ
มีความเห็นว่าตัวอย่างของ labeled tuple ช่วยป้องกันความผิดพลาดจากการสลับลำดับใน pair ได้ แต่ส่วนตัวชอบ anonymous record ของ F# มากกว่า
เช่น
{| product = 6; sum = 5 |}ที่ลำดับของ field ไม่มีความหมาย จึงไม่พลาดแบบนั้นใน fork นี้ immutable array ก็ถูกรวมเข้า 5.4 แล้วเช่นกัน ต่างกันแค่ syntax เล็กน้อย
ย้ำว่า anonymous labeled struct และ enum เป็นฟีเจอร์ลำดับต้น ๆ ที่อยากได้ในภาษาการเขียนโปรแกรม
ยกตัวอย่างว่าใน Rust สามารถนิยามได้ทั้ง labeled และ unlabeled struct
แต่ยังน่าเสียดายที่ใช้ anonymous labeled struct เป็นชนิดคืนค่าของฟังก์ชันไม่ได้
ไม่เคยรู้มาก่อนว่า fork นี้รองรับ SIMD
ถ้ามี unboxed type, ฟีเจอร์ allocation บน stack แบบชัดเจน และรองรับ Windows ด้วย ส่วนตัวมองว่า OxCaml อาจใช้งานได้ดีพอแทน F# ในบริบทผู้ใช้ทั่วไปอย่าง game dev
การรองรับ Windows ไม่ได้ติดขัดแบบเป็นไปไม่ได้ แต่ยังต้องมีงานเพิ่มอีกเล็กน้อย
ส่วนตัวอยากชี้ว่าการเพิ่มการรองรับ SIMD เป็นสิ่งที่ OxCaml ทำเอง
แชร์ทิปการตั้งค่า environment variable สำหรับคนที่ใช้ opam switch ใหม่
env OCAMLPARAM="alert=-unsafe_multidomain,_," opam install cohttp-lwt-unixช่วยแก้ปัญหาที่พอ alert ถูกยกระดับเป็น error แล้วทำให้การติดตั้งแพ็กเกจเดิมพังโดยไม่จำเป็น
สามารถปิด alert นี้ผ่าน environment variable
OCAMLPARAMเพื่อป้องกันปัญหาระหว่างติดตั้งได้คุ้นเคยกับ vscode plugin ที่ยอดเยี่ยมสำหรับ Golang เลยสงสัยว่าสภาพแวดล้อมของ OCaml มีแผนจะผสานกับ vscode หรือไม่
การผสานกับ vscode ทำให้การตั้งค่าง่ายขึ้นมาก
ถ้า OxCaml ได้รับความนิยมมากขึ้น ก็ย่อมมีโอกาสที่การผสานจะก้าวหน้าต่อไป
ส่วนตัวใช้ emacs เลยพูดรายละเอียดได้ไม่มาก แต่คาดว่าเป็นทิศทางที่เป็นธรรมชาติ
อยากพูดถึง OcaML เวอร์ชันขนาดจิ๋ว
ลิงก์โปรเจ็กต์ mlite
มีคนถามว่าเป้าหมายของการเปิดเผยโปรเจ็กต์นี้อาจเป็นเพราะต้องการให้ LLM นำข้อมูลไปทำดัชนีแล้วนำไปใช้กับโมเดลเปิดหรือไม่
มองว่าไม่น่าใช่เลย เพราะแม้แต่ข้อมูลเกี่ยวกับ OCaml ปกติก็ยังมีน้อยมากสำหรับ LLM และ OxCaml ยิ่งมีข้อมูลน้อยกว่าอีก
ถ้าจะทำเพื่อจุดประสงค์นี้ การสร้าง MCP สำหรับเอกสารของตัวเองน่าจะมีความหมายกว่า
ในฐานะสัญญาณ ข้อมูลนี้ยังไม่มีคุณค่ามากพอ จึงแทบไม่มีความหมาย
เช่น แม้แต่การเขียน Gleam ให้สมบูรณ์ LLM ก็ยังทำได้แย่มาก และต่อให้ให้รูปแบบที่ชัดเจนพร้อมข้อควรระวังเรื่องความผิดพลาดก็ยังล้มเหลว
เพราะแบบนี้จึงมองว่าสัญญาณยังอ่อนเกินไปสำหรับการให้ข้อมูลเกี่ยวกับ OxCaml
มุมที่น่าสนใจคือ OxCaml เป็นส่วนขยายของภาษาถิ่นหนึ่งในตระกูล ML ที่ต่อยอดจากภาษาถิ่นอีกชั้น
เลยรู้สึกอยากเห็นว่าขั้นต่อไปจะออกมาเป็นอย่างไร
เคยตั้งคำถามกับตัวเองว่า ระหว่างคนที่คอยเพิ่มฟีเจอร์ให้ภาษาที่มีอยู่ กับคนที่สร้างภาษาใหม่ตั้งแต่ต้น แบบไหนกันแน่ที่เป็นปัญหามากกว่า
ตัวเองอยู่ฝั่งหลัง แต่ก็คิดว่านักเขียนโปรแกรมมีลักษณะทางพันธุกรรมที่ปล่อยให้เครื่องมืออยู่เฉย ๆ ไม่ได้
มีการชวนแบบติดตลกว่า ถ้าอย่างนั้นช่วยแนะนำ F# ด้วยได้ไหม
มีการยืนยันว่าการที่โปรเจ็กต์นี้ใช้ชื่อ "oxidized" นั้นเกี่ยวกับเป้าหมายด้านฟีเจอร์แบบ Rust เช่น fearless concurrency และการหลีกเลี่ยง GC ไม่ใช่เพราะใช้ Rust จริง ๆ
จึงเป็นการตั้งชื่อที่อาจทำให้สับสนได้พอสมควร
มีคนอยากชี้ความย้อนแย้งเล็ก ๆ ว่าชื่อ Rust เองก็มาจากเชื้อรา "Rust" ไม่ใช่สนิม
แชร์ว่า Jane Street ทำบล็อกซีรีส์ชื่อ 'Oxidizing OCaml' มาตั้งนานแล้ว
คำนี้ยังถูกใช้ในชื่อบทความ "Oxidizing OCaml with Modal Memory Management" ด้วย แต่ในบทความก็ไม่ได้มีการนิยามหรืออ้างอิงคำว่า 'oxidize' อย่างชัดเจน
ถึงจะแปลกอยู่บ้าง แต่ก็ให้ความรู้สึกว่าเป็นชื่อที่ติดหูพอสมควร
มีการคาดการณ์ว่าฝั่ง Rust จะยังใช้งานได้จริงมากกว่า จนกว่าโปรเจ็กต์นี้จะมีความเท่าเทียมกับ Rust ในด้านการผสานเข้ากับ custom tracing GC ซึ่งสามารถจัดการโครงสร้างกราฟทั่วไปได้พร้อมกับไล่ประสิทธิภาพสูงสุด
ไม่เช่นนั้นก็อาจให้ความรู้สึกว่าแค่ยังคงใช้มันไว้เพราะมี codebase ที่เกี่ยวกับ OxCaml อยู่มากเท่านั้น