Hylo (Val) ภาษาโปรแกรมระบบระดับสูง
(val-lang.dev)- Hylo มุ่งสู่การเขียนโปรแกรมระบบและ generic programming ที่ปลอดภัยบนพื้นฐานของ value semantics โดยคอมไพเลอร์และไลบรารีมาตรฐานยังอยู่ใน ช่วงเริ่มต้น แต่สามารถลองรันตัวอย่างได้บน Compiler Explorer
- งานวิจัยของภาษามุ่งเน้นหัวข้ออย่างการขยาย inout projection ของ Swift subscript, method bundles, structured concurrency และ doubly-linked list บนพื้นฐานของ value semantics
- คอมไพเลอร์ใช้ LLVM และยังครอบคลุมการคอมไพล์ generics ที่มี coherence, การแคช·ซีเรียลไลซ์สถานะของโปรแกรม, และงานวิจัยด้าน C interop
- สภาพแวดล้อมการพัฒนามี VSCode extension, documentation compiler, และ Language Server prototype พร้อมรองรับ SPM/CMake, Ninja/Xcode, Windows/Linux/macOS, และอิมเมจ Docker toolchain สำหรับพัฒนา
- ตัวอย่างแสดงให้เห็นกฎของ ownership·deinitialization ในระดับโค้ดผ่าน safe projection และ sink method เพื่อสาธิตว่าภาษาเชิงระบบสามารถบังคับใช้ความปลอดภัยได้อย่างไร
ขอบเขตและสถานะปัจจุบันของ Hylo
- คอมไพเลอร์และไลบรารีมาตรฐานของ Hylo ยังอยู่ใน ช่วงเริ่มต้น
- สามารถลองรันตัวอย่างโค้ด Hylo ขั้นสูงได้ใน Compiler Explorer
- ในหน้าแรกก็มีลิงก์สำหรับลองใช้ Hylo บน Compiler Explorer เช่นกัน
Value semantics และงานวิจัยของภาษา
- MVS & Theory พัฒนาโดยเน้นที่ value semantics, safe projection, concurrency และการแทนโครงสร้างข้อมูล
- ขยาย subscript ของ Swift ให้เป็น inout projection
- Method bundles
- Structured concurrency made easy: structured concurrency ที่ไม่มี thread hopping และ function coloring
- วิธี แสดง doubly-linked list ด้วย value semantics ปลอดภัยและเร็วกว่า implementation แบบ reference semantics
คอมไพเลอร์และไลบรารีมาตรฐาน
- งานด้านคอมไพเลอร์ครอบคลุมการคอมไพล์บน LLVM, generics, state persistence และ C interop
- การคอมไพล์ด้วย LLVM
- เทคนิคใหม่ สำหรับการคอมไพล์ generics ที่มี coherence
- การแคช·ซีเรียลไลซ์ สถานะโปรแกรมของคอมไพเลอร์
- งานวิจัย C interop
- ฝั่งไลบรารีมาตรฐานกำลังเผยแพร่เอกสาร implementation ปัจจุบันและงานที่เกี่ยวข้องกับ collection algorithm
- เอกสาร implementation ปัจจุบัน มี trait และโครงสร้างข้อมูลพื้นฐานรวมอยู่
- Positionless Collection Algorithms
- rs-stl: การพอร์ตอัลกอริทึม C++ STL ไปยัง Rust เพื่อปรับปรุง generic programming
ประสบการณ์นักพัฒนาและสภาพแวดล้อมการบิลด์
- มีเครื่องมือสำหรับ editor, เอกสาร และ language server ให้ใช้งานร่วมกัน
- VSCode extension: รองรับ syntax highlighting และการรันโค้ด
- Documentation compiler
- Language Server prototype
- ระบบบิลด์และสภาพแวดล้อมการพัฒนารองรับหลายระบบปฏิบัติการและเวิร์กโฟลว์แบบคอนเทนเนอร์
- รองรับ Development Containers เพื่อลดขั้นตอนการเริ่มต้น
- รองรับ SPM/CMake, Ninja/Xcode, Windows/Linux/macOS
- compiler plugin สำหรับสร้างเทสต์
- อิมเมจ Docker แบบ prebuilt ของ Hylo development toolchain
- คอมไพเลอร์เขียนด้วย Swift 6.2
งานวิจัยและสื่อประกอบเกี่ยวกับ Hylo
- สื่อรอบ ๆ Hylo ถูกรวบรวมไว้เป็นบทความวิชาการ งานนำเสนอ และพอดแคสต์
- เอกสารและงานวิจัยล่าสุดมีรายการต่อไปนี้
- Who Owns the Contents of a Doubly-Linked List?, 2025-09
- High-Fidelity C Interoperability in Hylo, 2025-06
- Debugging Hylo, 2025-06
- On the State of Coherence in the Land of Type Classes, 2025-02
- Method Bundles, 2024-10
- Type Checking with Rewriting Rules, 2024-10
- Use Site Checking Considered Harmful, 2024-10
- Borrow checking Hylo, 2023-10
- The Val Object Model, 2022-10
- Implementation Strategies for Mutable Value Semantics, 2022
- งานนำเสนอครอบคลุม structured concurrency, ภาษาระบบและ generic language ที่ปลอดภัย, HyloDoc, borrow checking, การทำงานร่วมกับ C++, และ value semantics
- Hylo: The Safe Systems and Generic-programming Language Built on Value Semantics, C++ on Sea 2024-07
- HyloDoc: A Documentation Compiler for Hylo, C++ on Sea 2024-06
- Val: A Safe Language to Interoperate with C++, CppCon 2022-09
- Value Semantics: Safety, Independence, Projection, & Future of Programming, CppCon 2022-09
ตัวอย่างโค้ด: safe projection และ deinitialization แบบชัดเจน
- ตัวอย่าง Subscripts - A Safe Projection Mechanism แสดงโครงสร้างที่ชนิด
Angleเก็บค่าradiansและให้พร็อพเพอร์ตีdegreesผ่านบล็อกletและinoutdegreesของletจะแปลง radians เป็น degree แล้วคืนค่าinoutจะเปิดเผยค่า degree ชั่วคราวdด้วยyield &dแล้วแปลงค่าที่เปลี่ยนกลับเป็น radians เพื่อสะท้อนลงในself.radiansmainจะรับ projection ด้วยinout d = &a.degrees, เปลี่ยนdเป็น0.0แล้วตรวจสอบว่าa.radians == 0.0
- ตัวอย่าง Sink Methods - Capability for Deinitializing เป็นโครงสร้างที่ชนิด
Computerให้shutdown()เป็น sink methodshutdown()จะแสดงเนื้อหาในหน่วยความจำแล้วทำ sink กับself.ramtest1สร้างComputerแล้วไม่ shutdown จึงเกิดCannot deinit computertest2เรียก shutdown เฉพาะภายในif random_bool()ทำให้ในเส้นทางที่ไม่เข้าifเกิดCannot deinit computertest3ถ้าเรียก shutdown ภายในwhileจะเกิดปัญหาการใช้ object ที่ถูก consumed แล้วหลังรอบแรก และในเส้นทางที่ไม่เข้า while ก็ยัง deinit ไม่ได้
- ดูตัวอย่างเพิ่มเติมได้ใน compiler test suite
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
สำหรับผู้สืบทอดของ C++ บางที Val อาจน่าตื่นเต้นกว่า CppFront อันยอดเยี่ยมของ Herb Sutter ก็ได้ ตอนนี้ผมดูแค่สองพรีเซนเทชันด้านล่าง แต่ดูเหมือนแกนหลักจะเป็นการคอมไพล์แบบ static, static typing, การทำงานร่วมกับ C++, memory safety, type safety และไม่มี data race
เวลาอธิบายผมจะพูดว่า “ถ้าเริ่มโปรเจกต์ C++ ใหม่แล้วสมมติว่าไม่ได้กังวลเรื่องประสิทธิภาพ การส่งทุกอย่างเป็นค่าและคืนค่ากลับมาเป็นค่า โดยไม่มี pointer หรือ reference จะทำให้ไม่ต้องกังวลเรื่อง side effect หรือ data race ไม่ดีเหรอ” สิ่งที่น่าสนใจใน Val คือแม้ภาษาจะตัด pointer และ reference ออกไป แต่คอมไพเลอร์จะใช้การส่งผ่านแบบ const reference ภายในและ return value optimization เพื่อคงทั้ง semantics และประสิทธิภาพที่ต้องการไว้พร้อมกัน
Val: A Safe Language to Interoperate with C++ - Dimitri Racordon - CppCon 2022 https://www.youtube.com/watch?v=ws-Z8xKbP4w
https://cppcast.com/val-and-mutable-value-semantics/
https://adspthepodcast.com/
ผมคิดว่า PHP interpreter ฉลาดพอที่จะใช้ copy-on-write จริง ๆ แต่ไม่เคยทำ profiling เอง ถึงอย่างนั้นแม้จะทำ data processing ที่ค่อนข้างซับซ้อน, parsing DSL ระดับตัวอักษร, สร้าง SQL แบบ dynamic และจัดแต่งผลลัพธ์ให้อยู่ในโครงสร้างตามใจในทุก page load ก็ไม่เคยรู้สึกว่ามีปัญหาด้านประสิทธิภาพ
ในยุค PHP 4 แม้แต่ object ก็ทำงานเหมือนค่าที่เก็บอยู่ในตัวแปร แต่ตอนหลังที่เปลี่ยนตัวแปร object ให้เป็น reference semantics ผมมองว่าน่าเสียดายที่ไม่ได้ทำให้ “ค่า, การอ้างอิงตัวแปร, pointer ไปยังค่า” เป็นคุณสมบัติของตัวแปรที่ตั้งฉากกับชนิดข้อมูลที่เก็บ
$a = $b; // คัดลอกค่าของ $b ไปยัง $a$a = &$b; // ตอนนี้ $a และ $b เป็นตัวแปรเดียวกัน$a = *$b; // $a ชี้ไปยัง object เดียวกับ $b แต่ต่างจาก $a = &$b ตรงที่ตัวแปรเองไม่ได้เชื่อมกันการมีภาษาแบบ zero-cost abstraction โผล่มามากขนาดนี้ก็ดีในทางหนึ่ง แต่ก็แอบหวังว่านักเขียนโปรแกรมระบบจะเลือกผู้ชนะกันได้สักที ไม่อยากเห็นคอมมูนิตี้โปรแกรมเมอร์ระบบที่เดิมก็เล็กอยู่แล้ว ถูกแยกย่อยลงไปอีกเป็น Rust, Zig, Val และอื่น ๆ และอยากให้สงครามภาษา systems จบลงไว ๆ
วันนี้อารมณ์ตอนเพิ่งรู้จัก Val เป็นครั้งแรกประมาณนี้เลย “โอ้ ภาษา systems ใหม่แฮะ อาจไม่มีอะไร แต่ลองดูหน่อย เอกสารใช้ได้ ไอเดียเรื่อง ownership ก็ค่อนข้างรอบคอบ syntax ก็สมเหตุสมผล แต่ต่างพอจะมีเหตุผลในการมีอยู่เป็นของตัวเองไหม ใครเป็นคนทำกันนะ?”
แล้วพอเห็นว่า Dave Abrahams กำลังทำอยู่ก็สนใจขึ้นมาเลย ผมเคยเจอเขาที่ Apple และยังจำ Crusty talk เรื่อง Swift ได้ ผมชอบความเห็นที่ชัดเจนหนักแน่นของเขา แต่ภายหลัง Apple ก็เอาวิดีโอนั้นลงด้วยเหตุผลว่ามีคำแนะนำที่ล้าสมัยอยู่ ตอนนี้เขาอยู่ที่ Adobe งั้นนี่คือภาษา Adobe หรือเปล่านะ
สรุปคือเป็นสิ่งที่คุ้มค่าจะจับตาดู และหลังจากดูพรีเซนเทชันที่ลิงก์ไว้แล้วก็คงต้องรอต่อไป
[1] หา Crusty talk เจอแล้ว: "I don't do Object Oriented!" https://www.youtube.com/watch?v=p3zo4ptMBiQ
ในฐานะนักพัฒนาคอมไพเลอร์ รู้สึกช็อกจาก issue ข้างล่างนี้
https://github.com/val-lang/val/issues/758
https://github.com/val-lang/val/issues/711
มันมีกลิ่นว่าคุณภาพสถานะการพัฒนายังไม่ดีนัก ควร self-hosting ให้ได้โดยเร็วที่สุด และถ้าทำได้ก็น่าจะเจอบั๊กพื้นฐานแบบนี้มากขึ้น ถึงอย่างนั้นก็ยังมีดาวเกิน 500
การ self-hosting ก็ไม่ใช่ทั้งหมด เหนือสิ่งอื่นใดมันใกล้เคียงกับหลักไมล์เชิงสัญลักษณ์มากกว่า ทำได้เมื่อไรก็น่ายินดี แต่ไม่คิดว่าจนกว่าจะเลยไปอีกมากในวงจรพัฒนา มันควรถูกนับเป็นจุดอ่อนของภาษา
เลื่อน “ลองเล่น Val” มานาน วันนี้เพิ่งได้ลองสักที แต่ถึงจะมีคอมมิตเกิน 4,000 แล้ว ก็ยังห่างไกลจากสภาพที่ใช้งานได้จริง ตัวอย่างส่วนใหญ่ในหน้าพาชมภาษาคอมไพล์ไม่ผ่าน และแม้แต่ตัวอย่างที่ดูเรียบง่ายก็ยังล้มเหลว
Carbon ก็ยังไม่มีอะไรที่ออกมาเป็นชิ้นเป็นอัน ส่วน Sean Baxter ก็กำลังก้าวหน้าไปมากกับคอมไพเลอร์ Circle และได้นำส่วนดีหลายอย่างของ Carbon ไปทำแล้ว ถ้ายังยากจะเรียกว่าเป็นภาษา ก็ยากจะเป็นผู้สืบทอดได้เช่นกัน
ตอนนี้มี V, Val, Vala, Vale แล้ว ยังมีภาษาอื่นที่ผมลืมอีกไหม?
เป็นประเด็นที่พูดกันทุกครั้ง แต่สิ่งเดียวที่ผมไม่ชอบใน Val คือ Vale กับ V ก็เป็นภาษาระบบใหม่เหมือนกัน ทำให้ทั้งสามสับสนกันได้ง่ายมากเพราะชื่อ
มีโพสต์ที่เกี่ยวข้องอยู่ อันอื่นมีอีกไหม?
Val, a new programing language inspired by Swift and Rust - https://news.ycombinator.com/item?id=31788527 - มิถุนายน 2022, ความคิดเห็น 19 รายการ
ผมลองไล่อ่านคร่าวๆ งานวิจัย “mutable value semantics” แล้วสงสัยว่าควรเข้าใจว่าผู้เขียนเสนอให้แทนที่ reference และ pointer ด้วย a) การอ้อมผ่านบางส่วนและการตรวจสอบตอนรันไทม์ผ่าน nested struct กับ
Any, b) array index หรือไม่มีช่วงหนึ่งที่สะดุดตาว่า “เป็นคำถามที่สมเหตุสมผลว่าด้วย mutable value type จะนิยามโครงสร้างข้อมูลแบบอ้างอิงตัวเอง เช่น doubly linked list หรือ directed graph ได้อย่างไร ที่จริงแล้วกราฟใดๆ ก็แทนได้ด้วย adjacency list …” ผมยังมองไม่ออกว่าจะทำ doubly linked list ให้สมเหตุสมผลได้อย่างไร โดยไม่ลงเอยด้วยการสร้าง memory heap และอะไรคล้ายๆ garbage collection ขึ้นมาใหม่ภายในการ implement
เพิ่มเติม ผมไปเจอการถกเถียงที่ https://github.com/orgs/val-lang/discussions/736 และดูเหมือนว่าจะมีทางหนีแบบ
unsafeของ Rust โผล่มา ถ้าเป็นอย่างนั้นปัญหาทุกอย่างก็แก้ได้ แต่คำถามว่า “ชุดย่อยที่ปลอดภัยของ Val เพียงอย่างเดียวพอสำหรับสร้างแอปพลิเคชันที่ใช้งานได้จริงหรือไม่” คงจะยังเป็นประเด็นถกเถียงไปอีกนานที่มันอาจไม่ได้เป็นวิธีที่โง่อย่างที่คิด ก็เพราะดัชนีเหล่านี้ถูกผูกไว้กับโครงสร้างข้อมูลเฉพาะ เช่น doubly linked list หรือกราฟ จึงไม่ง่ายที่จะบิดมันให้ไปเข้าถึงส่วนอื่นของโปรแกรม นี่รวมถึงกรณีที่คอมไพเลอร์ตรวจสอบสิ่งนี้ด้วย หรือแม้แต่เมื่อพยายามทำโปรแกรมให้พัง
ไม่ค่อยรู้ว่าควรอ่านคำอธิบายในตัวอย่างบนหน้าเว็บอย่างไร เขาบอกว่า “จะไม่เกิดการจัดสรรที่ไม่จำเป็นขึ้น ผลลัพธ์ของ
longer_ofคือ projection ของอาร์กิวเมนต์ที่ยาวกว่า ดังนั้นถ้าemphasizeเปลี่ยนค่า z ก็จะเป็นการเปลี่ยนค่า y โดยตรง ค่าจะไม่ถูกคัดลอกและไม่ถูกย้าย แต่ก็ไม่ได้ถูกส่งเข้าemphasizeแบบอ้างอิงด้วย”เป็นสถานการณ์ที่อาร์กิวเมนต์สตริงถูกส่งเข้าไปในฟังก์ชันแล้วมีการต่ออักขระเพิ่ม แต่เดิมสตริงก็น่าจะมีความยาวตั้งต้น รวมถึงตำแหน่งและขนาดบางอย่างบนสแตกอยู่แล้ว เลยไม่เข้าใจว่าจะทำแบบนั้นได้อย่างไรโดยไม่ต้องมีสำเนาใหม่ของ y หรือเขาเผื่อ padding ไว้ท้ายสตริงสำหรับกรณีที่อาจมีใครมา append? ถ้าใช่ จะเผื่อไว้เท่าไร แล้วทำไมภาพรวมถึงไม่ยิ่งไร้ประสิทธิภาพกว่าเดิม?
>เพื่ออ้างอิง ซึ่งใช้ได้ดีแม้พาร์เซอร์จะไม่ได้รองรับเป็นพิเศษแต่ก็มีคำถามคล้ายกันอยู่เหมือนกัน ถ้าแก้ไข สตริงขนาด 1GB จะเกิดอะไรขึ้น? เป็น copy-on-write หรือเปล่า?
99% ของกรณีอาจถูก optimization กำจัดทิ้งได้ แต่รู้สึกว่าในอีก 1% ที่เหลืออาจเกิดปัญหาประสิทธิภาพที่หายากและตามหายากมาก
longer_ofไม่ใช่ฟังก์ชัน แต่เป็น subscript และ subscript จะไม่คืนค่า แต่จะทำ projection ของค่าเพื่อให้สิทธิ์การเข้าถึงแบบอ่าน/เขียนชั่วคราวแก่ผู้เรียกยังไม่ค่อยเข้าใจว่าสิ่งนี้นับว่าไม่ใช่การย้ายได้อย่างไร สำหรับสตริงแล้วอาจเก็บไว้บนฮีปเพื่อให้รองรับขนาดที่เปลี่ยนแปลงได้เหมือน Rust