• Flix เป็น ภาษาเชิงเอฟเฟกต์ ที่พัฒนาโดย Aarhus University และชุมชนโอเพนซอร์ส โดยผสานการเขียนโปรแกรมเชิงฟังก์ชัน เชิงคำสั่ง และเชิงตรรกะไว้ในภาษาเดียว
  • แกนหลักคือ ระบบเอฟเฟกต์ ที่จัดการผลข้างเคียงในระดับชนิดข้อมูล ช่วยเพิ่มความเป็นโมดูลาร์และความสามารถในการให้เหตุผลของโปรแกรมผ่านการติดตามความบริสุทธิ์ เอฟเฟกต์ที่ผู้ใช้กำหนดเอง แฮนด์เลอร์ และการ resume ได้หลายครั้ง
  • ผิวหน้าของภาษาครอบคลุมกว้าง ตั้งแต่ชนิดข้อมูลเชิงพีชคณิต, pattern matching, record ที่ขยายได้, trait, higher-kinded type, associated type และ effect, structured concurrency, การทำงานร่วมกับ Java ไปจนถึง Datalog ในตัว
  • ไลบรารีมาตรฐานมี ฟังก์ชันมากกว่า 3,100 รายการ และเข้าถึงระบบนิเวศ Java ผ่าน Maven ได้ จึงมุ่งให้ใช้งานได้กว้างกว่าภาษาเพื่อการวิจัยเท่านั้น
  • คอมไพเลอร์มุ่งเป้าไปที่ JVM bytecode มีโครงสร้างแบบขนานและ incremental โดยชูตัวเลข เร็วขึ้น 5x–7x บนเครื่อง 24 คอร์ และ throughput 60,159 lines/sec บน Apple M2 Pro/OpenJDK 21

ทิศทางของภาษา Flix

  • Flix เป็น ภาษาเชิงเอฟเฟกต์ที่ยึดหลักการ โดยผสานการเขียนโปรแกรมเชิงฟังก์ชัน เชิงคำสั่ง และเชิงตรรกะ
  • ผู้พัฒนาหลักคือ Aarhus University และชุมชน ผู้ร่วมพัฒนาโอเพนซอร์ส
  • ระบบเอฟเฟกต์เป็นแกนสำคัญของภาษาแบบ static typing ที่ช่วยเรื่อง ความเป็นโมดูลาร์ และการให้เหตุผลเกี่ยวกับโปรแกรม ด้วยการจำลองผลข้างเคียงอย่างชัดเจน
  • โปรแกรมเมอร์สามารถสร้างโครงสร้างควบคุมเองได้ผ่านเอฟเฟกต์และแฮนด์เลอร์ที่ผู้ใช้กำหนดเอง
  • Flix ชูจุดแข็งด้าน implementation ที่สมบูรณ์ในกลุ่มภาษาเชิงเอฟเฟกต์ ไลบรารีมาตรฐานที่กว้าง เอกสารละเอียด และการรองรับเครื่องมือ

ชนิดข้อมูล ความบริสุทธิ์ และระบบเอฟเฟกต์

  • Flix รองรับ ชนิดข้อมูลเชิงพีชคณิต และ pattern matching ซึ่งเป็นองค์ประกอบพื้นฐานของการเขียนโปรแกรมเชิงฟังก์ชัน
  • รองรับ tuple และ record ในตัว โดย record ใช้ structural typing และขยายได้
  • คอมไพเลอร์ติดตาม ความบริสุทธิ์ ของทุก expression ในโปรแกรมอย่างละเอียด
    • หาก expression บริสุทธิ์ จะรับประกันว่าไม่มีผลข้างเคียงและมี referential transparency
  • แม้ใน higher-order function ก็ยังติดตามความบริสุทธิ์ด้วย effect polymorphism
    • ตัวอย่างเช่น ความบริสุทธิ์ของ List.map ขึ้นอยู่กับความบริสุทธิ์ของฟังก์ชัน f ที่รับมาเป็นอาร์กิวเมนต์
  • algebraic effect ทำให้สร้างเอฟเฟกต์และแฮนด์เลอร์ที่ผู้ใช้กำหนดเองได้
    • Flix รองรับ multi-shot resumptions เป็นพิเศษ
    • effect handler ใช้เพื่อเพิ่มความสามารถในการให้เหตุผลเกี่ยวกับโปรแกรม ความเป็นโมดูลาร์ และความสามารถในการทดสอบ

การเปลี่ยนแปลงแบบอิง region และการสะท้อนความบริสุทธิ์

  • Flix รองรับ การเปลี่ยนแปลงภายในแบบอิง region ทำให้สามารถใช้สถานะที่แก้ไขได้และการดำเนินการแบบทำลายค่าเดิมภายในได้ แต่ภายนอกยังดูเป็นฟังก์ชันบริสุทธิ์
  • เหมาะกับฟังก์ชันที่เขียนด้วยข้อมูลที่แก้ไขได้แล้วเป็นธรรมชาติกว่า หรือกรณีที่โครงสร้างข้อมูลแบบแก้ไขได้มีประสิทธิภาพกว่าสำหรับอัลกอริทึมอย่างการเรียงลำดับ
  • การสะท้อนความบริสุทธิ์ เป็นโครงสร้าง metaprogramming ที่ higher-order function ตรวจสอบความบริสุทธิ์ของอาร์กิวเมนต์ฟังก์ชัน และเปลี่ยนพฤติกรรมตามข้อมูลนั้น
    • DelayList.map เปลี่ยนพฤติกรรมระหว่างการประเมินผลทันทีและการประเมินผลแบบ lazy ตามความบริสุทธิ์ของฟังก์ชันอาร์กิวเมนต์
    • แม้ภายในไลบรารีจะเลือกใช้การประเมินผลแบบ lazy หรือแบบขนาน ความหมายในมุมมองของ client ก็อาจไม่เปลี่ยน

ความขนาน ความพร้อมกัน และ abstraction

  • Flix ทำให้ประเมินผลโค้ดบริสุทธิ์แบบขนานได้ง่าย และสามารถเขียน implementation แบบขนานของ List.map ด้วยโครงสร้าง par
  • โครงสร้าง par ใช้ VirtualThread แบบ lightweight ภายใน
  • รองรับ structured concurrency โดย thread ที่สร้างภายใน region หนึ่งจะไม่สามารถมีชีวิตอยู่นอก lifecycle ของ region นั้นได้
    • ในตัวอย่าง มีการสร้าง thread สองตัวใน region ใหม่ชื่อ rc
    • control flow จะไม่ออกจาก region จนกว่า thread ทั้งสองจะสิ้นสุด
  • การทำ abstraction ของชนิดข้อมูลที่รองรับ operation ร่วมกันใช้ trait
    • trait Eq แสดงแนวคิดของความเท่ากัน และใช้ทั่วไลบรารีมาตรฐาน
  • higher-kinded type ทำให้ทำ abstraction เหนือ type constructor ได้
    • ทั้ง Option และ List implement Foldable
    • ไลบรารีมาตรฐานมี trait ทั่วไปอย่าง Monoid, Functor, Foldable

Associated type/effect และ for-yield

  • Flix รองรับ associated type ที่ทำให้ชนิดข้อมูลใน signature ของ instance ขึ้นกับชนิดของ instance ได้
    • ตัวอย่าง trait Coll ทำให้แต่ละ collection instance กำหนดชนิดของ element ได้ผ่าน associated type Elm
  • Associated effect ทำให้เอฟเฟกต์ของสมาชิก trait ขึ้นกับชนิดของ instance
    • ช่วยให้ abstract operation บริสุทธิ์กับ operation ที่มีเอฟเฟกต์ รวมถึงโครงสร้างข้อมูลแบบแก้ไขได้กับแบบ immutable ได้ง่ายขึ้น
    • เมื่อเพิ่ม associated effect Aef ให้ trait Coll ก็สามารถเพิ่ม instance ของ collection แบบแก้ไขได้
  • forM-yield เป็นโครงสร้างแบบ monadic ที่คล้าย for-comprehension ของ Scala และสัญกรณ์ do ของ Haskell
    • เป็น syntax sugar สำหรับใช้ point และ flatMap ที่ trait Monad ให้มา
  • forA เป็น expression แบบ applicative ที่อิง trait Applicative
    • เป็นโครงสร้างที่ช่วยให้เขียนโค้ดจัดการข้อผิดพลาดโดยใช้ชนิดข้อมูล Validation[e, t] ได้ง่ายขึ้น

การทำงานร่วมกับ Java และ Datalog

  • Flix รองรับ การทำงานร่วมกับ Java เพื่อใช้ Java Standard Library และโค้ดจากระบบนิเวศ Java ซ้ำได้
    • รวมถึงการเข้าถึงระบบนิเวศผ่าน Maven
    • รองรับการสร้าง object, การเรียก method, exception, และการขยาย class/interface
  • การรองรับ Datalog ในตัวเป็นหนึ่งในความสามารถเฉพาะของ Flix
    • Datalog สามารถแสดงปัญหา fixed point หลายแบบอย่างกระชับ รวมถึงปัญหา reachability ของกราฟ
  • Datalog constraint เป็น first-class value
    • ส่งให้ฟังก์ชันหรือคืนค่าจากฟังก์ชันได้
    • เก็บไว้ในโครงสร้างข้อมูลได้
    • ประกอบกับ Datalog constraint อื่นและแก้ได้
    • ทำให้แสดงกลุ่มของโปรแกรม Datalog ได้
  • Flix ยังรองรับ Datalog constraint ที่เสริมด้วย lattice semantics
    • มีตัวอย่างการคำนวณวันส่งมอบของชิ้นส่วนและชิ้นส่วนย่อย
    • รถยนต์ขึ้นกับแชสซีและเครื่องยนต์ และประกอบรถได้หลังรอให้แต่ละชิ้นส่วนประกอบเสร็จ
    • ชิ้นส่วนย่อยก็อาจขึ้นกับชิ้นส่วนย่อยอื่น ทำให้ปัญหาเป็นแบบ recursive
  • Datalog constraint ที่รวม lattice semantics เป็นหนึ่งในฟีเจอร์ขั้นสูงของ Flix และต้องมีพื้นฐานด้าน lattice theory กับ fixed point

ไลบรารีมาตรฐานและรายการฟีเจอร์

  • Flix มีไลบรารีมาตรฐานที่ให้ ฟังก์ชันมากกว่า 3,100 รายการ
    • โมดูล List ให้ฟังก์ชันมากกว่า 100 รายการ
    • trait Foldable ให้ฟังก์ชันมากกว่า 47 รายการ
    • สามารถสำรวจไลบรารีทั้งหมดได้ที่ api.flix.dev
  • รายการฟีเจอร์ประกอบด้วย
    • ชนิดข้อมูลเชิงพีชคณิต, pattern matching, first-class function
    • record ที่ขยายได้, parametric polymorphism
    • trait, higher-kinded type, associated type และ effect
    • effect polymorphism และ sub-effect, การสะท้อนความบริสุทธิ์
    • concurrency สไตล์ CSP, channel แบบมี buffer และไม่มี buffer
    • first-class Datalog constraint, การทำงานร่วมกับ Java
    • primitive type แบบ unboxed, syntax แบบใช้ keyword
    • forM, forA, expression hole
    • การคอมไพล์เป็น JVM bytecode, การกำจัด tail call อย่างสมบูรณ์
    • โครงสร้างคอมไพเลอร์แบบยืดหยุ่นและขนาน, ข้อผิดพลาดที่มนุษย์อ่านเข้าใจง่าย

โครงสร้างและประสิทธิภาพของคอมไพเลอร์

  • คอมไพเลอร์ Flix มีโครงสร้างแบบ ยืดหยุ่น incremental และขนาน
  • ทุกขั้นตอนของคอมไพเลอร์ทำงานแบบขนาน และสามารถใช้ประโยชน์จากความเร็วที่เพิ่มขึ้นของแต่ละขั้นตอนบนเครื่อง 24 คอร์ได้
  • บนเครื่อง multicore สามารถทำความเร็วเพิ่มขึ้นได้ 5x–7x
  • เมื่อคอมไพล์โค้ดที่เคยคอมไพล์แล้วอีกครั้งใน instance คอมไพเลอร์เดียวกัน จะได้ความเร็วเพิ่มขึ้นอย่างมากจาก incremental compilation
  • ตัวเลขประสิทธิภาพบน CPU Apple M2 Pro 10 คอร์ และ OpenJDK 21 มีดังนี้
    • throughput รวมของคอมไพเลอร์: 60,159 lines/sec
    • throughput เฉพาะ frontend: 140,382 lines/sec
    • คำสั่งสำหรับทำซ้ำคือ java -jar flix.jar Xperf --n 21 และ java -jar flix.jar Xperf --frontend --n 21
  • ประสิทธิภาพนี้ทำได้พร้อมกับรองรับฟีเจอร์ของภาษาที่มีต้นทุนสูง เช่น type/effect inference, monomorphization และ whole-program optimization
  • ประสิทธิภาพคอมไพเลอร์ขึ้นอยู่กับประสิทธิภาพ CPU และ memory bandwidth เป็นหลัก

การรองรับ Visual Studio Code และการผสานเครื่องมือ

  • คอมไพเลอร์ Flix ผสานกับ Visual Studio Code เพื่อให้สภาพแวดล้อมการพัฒนา
  • ส่วนขยาย VSCode ใช้คอมไพเลอร์ Flix จริง จึงมี ความสอดคล้องแบบ 1:1 ระหว่างส่วนขยายกับคอมไพเลอร์
    • หาก VSCode ไม่รายงานข้อผิดพลาด แปลว่าไม่มีข้อผิดพลาด
    • เมื่อไม่มีข้อผิดพลาด VSCode จะไม่รายงานข้อผิดพลาดปลอม
  • ส่วนขยาย VSCode รองรับฟีเจอร์ต่อไปนี้
    • syntax highlighting ตามความหมาย
    • diagnostics ข้อผิดพลาดจากคอมไพเลอร์แบบ inline
    • autocomplete ระหว่างพิมพ์, autocomplete ตามบริบท, autocomplete trait instance, การเติม hole ตามชนิดข้อมูล
    • snippet และ inlay hint
    • hover ที่แสดงชนิดข้อมูลและเอฟเฟกต์ของ expression
    • ไปยังนิยามของฟังก์ชัน ตัวแปรท้องถิ่น และ enum
    • ค้นหา reference ของฟังก์ชัน ตัวแปรท้องถิ่น และ enum รวมถึงค้นหา implementation ของ trait
    • รายการ symbol ของเอกสารและ workspace
    • เปลี่ยนชื่อตัวแปรท้องถิ่นและฟังก์ชัน
    • รัน main และรันทดสอบจาก editor
  • Flix ฝังเครื่องมือจำนวนมากไว้ในคอมไพเลอร์โดยตรง
    • OCaml ใช้ ocaml-lsp เป็น LSP, utop เป็น REPL, dune เป็น build tool และ opam เป็น package manager
    • Haskell ใช้ HLS เป็น LSP, ghci เป็น REPL, cabal และ stack เป็น build tool และ package manager และใช้ Hackage เป็น package repository
    • Flix ให้คอมไพเลอร์, LSP, REPL, build tool และ package manager ทั้งหมดผ่าน flix และใช้ GitHub เป็น package repository

สถานะการพัฒนา เป้าหมาย JVM และขนาดโปรเจกต์

  • Flix พัฒนาและดูแลโดยนักวิจัยด้านภาษาโปรแกรมจาก Aarhus University ประเทศเดนมาร์ก
  • สถาบันที่ร่วมมือกันคือ University of Waterloo ในแคนาดา, University of Tubingen ในเยอรมนี และ Copenhagen University ในเดนมาร์ก
  • การมีส่วนร่วมพัฒนาจากชุมชนโอเพนซอร์สทั่วโลกกำลังเพิ่มขึ้น และเปิดรับผู้ร่วมพัฒนา
  • สถิติโปรเจกต์มีดังนี้
    • Pull Request ที่ merge แล้ว: มากกว่า 4,900 รายการ
    • issue ที่แก้แล้ว: มากกว่า 3,100 รายการ
    • ผู้ร่วมพัฒนา: มากกว่า 70 คน
    • codebase ของคอมไพเลอร์: มากกว่า 272,000 บรรทัด
  • Flix มุ่งเป้าไปที่ JVM
    • JVM มี implementation ทั้งโอเพนซอร์สและเชิงพาณิชย์ที่ผ่านการพิสูจน์แล้ว เช่น OpenJDK, J9, Azul, Graal
    • ใช้งานได้บน Mac, Linux, Windows
    • JVM สมัยใหม่มี garbage collector รุ่นใหม่หลายแบบ
    • รองรับ concurrency และ parallelism ได้ดี รวมถึง lightweight thread ของ Java 21
    • มีการรองรับเครื่องมือ เช่น debugger และ profiler
    • การผสานกับ Maven ทำให้เข้าถึงระบบนิเวศแพ็กเกจอันหลากหลายของแพลตฟอร์ม Java ได้
  • เงินทุนรวมอยู่ที่ 1.1 ล้านยูโร ซึ่งช่วยรับประกันความต่อเนื่องและความเป็นอิสระของโปรเจกต์

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น