กำลังมีการพอร์ต Bun (รันไทม์ JavaScript) จาก Zig ไปเป็น Rust แบบไวบ์พอร์ต
(github.com/oven-sh)- Jarred Sumner ผู้ก่อตั้ง Bun ได้คอมมิต คู่มือพอร์ต Zig → Rust (PORTING.md) ลงในสาขา
claude/phase-a-portทำให้มีการเปิดเผยการทดลองเปลี่ยนภาษาโค้ดครั้งใหญ่โดยใช้งานเอเจนต์ AI - การพอร์ตแบ่งเป็น Phase A (แปลเฉพาะลอจิกในระดับไฟล์แบบร่างแรก ยังไม่จำเป็นต้องคอมไพล์ได้) และ Phase B (คอมไพล์ผ่านในระดับ crate) โดยใช้วิธีป้อนกฎแมปชนิดข้อมูลและสำนวนการเขียนราว 300 ข้อให้ LLM
- ตัว Sumner เองได้ระบุใน Hacker News ว่า "ยังไม่ได้ตัดสินใจว่าจะรีไรต์จริง และมีโอกาสสูงที่โค้ดนี้จะถูกทิ้งทั้งหมด" ทำให้ ณ ตอนนี้ยังอยู่ในขั้นทดลองสำรวจ
- ในชุมชนมีการพูดถึงปัจจัยเบื้องหลัง เช่น ความขัดแย้งกับ นโยบายห้ามการมีส่วนร่วมจาก AI ของ Zig หลังการเข้าซื้อโดย Anthropic, การที่ Bun ดำเนินงานบนฟอร์กของ Zig อยู่แล้ว, และข้อได้เปรียบด้านความปลอดภัยของ ecosystem ฝั่ง Rust
- PR ส่วนใหญ่ถูกสร้างอัตโนมัติโดย @robobun (บอต AI) และมี CodeRabbitAI กับ Claude ช่วยรีวิว เป็นตัวอย่างที่แสดงทั้งความเป็นไปได้จริงและข้อจำกัดของการย้ายโค้ดขนาดใหญ่ที่ขับเคลื่อนด้วย AI
โครงสร้างสำคัญของคู่มือพอร์ต (PORTING.md)
- เป้าหมายของการพอร์ตคือแปลงไฟล์ Zig ทีละไฟล์เป็นไฟล์
.rsในไดเรกทอรีเดียวกัน โดยใน Phase A เป้าหมายคือ ถ่ายทอดลอจิกอย่างซื่อตรง และไม่สนว่าคอมไพล์ได้หรือไม่ - ห้ามใช้ external async และ I/O crate เช่น
tokio,rayon,hyper,async-trait,std::fs,std::netเนื่องจาก Bun มี event loop และ syscall ของตัวเอง - ห้ามใช้
async fnโดยการประมวลผล asynchronous ทั้งหมดต้องคงรูปแบบ callback + state machine เหมือน Zig - ส่วนที่ยังไม่มั่นใจให้ทำเครื่องหมาย
// TODO(port):และสำนวน Zig ที่เกี่ยวกับประสิทธิภาพให้ทำเครื่องหมาย// PERF(port):เพื่อไปจัดการใน Phase B
กฎการแมปชนิดข้อมูลและสำนวนการเขียน
- มีการให้ ตารางแมปชนิดข้อมูลมากกว่า 50 รายการ เช่น
[]const u8→&[u8](ห้ามใช้&strเด็ดขาด),?T→Option<T>,anyerror!T→Result<T, bun_core::Error> defer x.deinit()→ ลบออกแล้วแทนด้วยimpl Drop,errdefer→ ใช้scopeguard,comptime→ แปลงเป็น const generic,const fn,macro_rules!- สตริงใช้หลักการประมวลผลแบบ อิงไบต์: ห้ามใช้
std::string::Stringหรือ&strและให้ใช้&[u8]/Vec<u8>แทน เนื่องจาก Bun จัดการทั้ง WTF-8 และไบต์ตามอำเภอใจ - มีการสรุป คู่เทียบใน Rust สำหรับฟังก์ชัน built-in ของ Zig เช่น
@intCast→T::try_from(x).unwrap()(ตรวจสอบเสมอ),@truncate→x as T(ตั้งใจให้ wrap),@bitCast→transmute
แผนที่ crate และโมเดล ownership
- Zig namespace อย่าง
@import("bun").Xถูกแมปแบบ 1:1 ไปยัง Rust crate ราว 30 ตัว เช่นbun_str,bun_sys,bun_jsc,bun_alloc - crate ฝั่ง AST/parser ยังคงใช้อารีนา
bumpalo::Bumpส่วน crate อื่น ๆ จะใช้ global mimalloc allocator และลบ allocator parameter ออก - มีการแมป ownership ของ pointer เช่น
bun.ptr.Owned→Box<T>,bun.ptr.Shared→Rc<T>,bun.ptr.AtomicShared→Arc<T>
ปฏิกิริยาจากชุมชน (Lobsters·HN)
- มีความเห็นจำนวนมากที่ตั้งคำถามว่า "กำลังจะย้ายไป Rust จริง หรือเป็นเพียงโชว์เคสของ Anthropic LLM"
- มีการคาดเดาว่าอาจมีฉากหลังเป็นความขัดแย้งระหว่าง นโยบายห้าม AI มีส่วนร่วมของ Zig กับเวิร์กโฟลว์การพัฒนาที่เน้น AI ของ Anthropic แต่ก็มีการประเมินกันเองว่ายังออกไปทางทฤษฎีสมคบคิด
- มีมุมมองเชิงสงสัยว่า LLM จะทำตามกฎราว 300 ข้อได้อย่างเคร่งครัดหรือไม่ ขณะเดียวกันก็มีความเห็นเชิงบวกว่า "ประมาณ 16k โทเคน ถือว่าพอดีสำหรับซับเอเจนต์"
- มีข้อสังเกตที่น่าสนใจว่าแนวทาง สร้างโค้ดที่ยังคอมไพล์ไม่ได้ก่อนใน Phase A นั้นตรงข้ามกับวิธีใช้ coding agent แบบเดิม ๆ
- ภาระในการดูแลฟอร์กของ Zig สำหรับ Bun, breaking change ที่เกิดขึ้นบ่อยใน Zig, และความเสี่ยงจากการพึ่งพาภาษาในขั้นเบตาสำหรับผลิตภัณฑ์หลัก ถูกยกขึ้นมาเป็นแรงจูงใจของการย้ายครั้งนี้
1 ความคิดเห็น
ความเห็นจาก Lobste.rs
อนึ่ง สิ่งที่ Jarred Sumner พูดไว้บน HN เกี่ยวกับเรื่องนี้มีดังนี้: เขาเป็นผู้ทำงานกับ Bun และนี่เป็น branch ของเขาเอง โดยมองว่าเธรดนี้เป็นการตอบสนองเกินเหตุต่อ โค้ดที่ยังใช้งานไม่ได้
ยังไม่ได้ยืนยันว่าจะเขียนใหม่จริง และมีความเป็นไปได้สูงมากว่าโค้ดทั้งหมดนี้จะถูกทิ้งไป
เขาอยากเห็นว่ารุ่นที่ใช้งานได้จริงจะมีหน้าตาอย่างไร ประสิทธิภาพเป็นอย่างไร ความยากในการทำให้ผ่าน Bun test suite และดูแลรักษาได้อยู่ระดับไหน และอยากเปรียบเทียบ เวอร์ชัน Rust กับเวอร์ชัน Zig แบบวางขนานกันว่าทำได้แค่ไหน
การตีความเทคโนโลยีแบบวัฒนธรรมมวลชนส่วนใหญ่มักพึ่งพา ปฏิกิริยาฉับพลัน
pull request ทั่วไปของ Bun เองก็ค่อนข้างเป็นระเบียบแบบโกลาหล: https://github.com/oven-sh/bun/pulls?q=is%3Apr+
ส่วนใหญ่ @robobun เป็นคนสร้างแบบอัตโนมัติ มีการเช็กความซ้ำด้วย GitHub Actions (อิง Claude) และให้ @coderabbitai กับ @claude ช่วยรีวิว
ระหว่างนั้น CI ก็พังอยู่ และ @robobun ก็สุดท้ายปิด PR บางอันของตัวเองเพราะซ้ำกับ PR อื่นที่ตัวเองทำไว้
ส่วนการ merge เข้า main ยังเป็นคนทำอยู่
จำได้ว่า Bun เคยได้รับคำชมเพราะ ความหมกมุ่นเรื่องประสิทธิภาพ ของ Jarred แต่ไม่คิดว่าจะปล่อยให้ LLM วิ่งพล่านใน codebase ขนาดนี้
นี่ดูไม่เข้าท่าเลย
พอดู “การแมป idiom” แล้วมี
unsafeเต็มไปหมด และน่าจะได้ โค้ดที่ไม่เป็น Rust แบบ Rust ออกมาจำนวนมากโดยเฉพาะการแมป
@fieldParentPtr("field", ptr)ดูหยาบมากอย่างไรก็ดี ดูเหมือนว่า “phase A” จะเป็นการแปลแทบจะระดับบรรทัดต่อบรรทัด และค่อยใช้ prompt ในภายหลังเพื่อรีแฟกเตอร์ให้เป็น Rust ที่เป็นธรรมชาติและดูแลรักษาได้มากขึ้น
ปัญหาคือการออกแบบภาษาสามารถผลักทิศทางการ implement ได้แรงมาก และในทางปฏิบัติก็เป็นเช่นนั้นจริง จึงมีโอกาสสูงที่จะเกิดปมที่คลายทีหลังยาก
สุดท้ายแล้วการ เขียนใหม่ด้วยมือ แบบดั้งเดิมน่าจะเป็นทางที่ดีกว่า
โดยเฉพาะถ้ามีเงินทุนระดับ Anthropic ข้อดีของ AI คือมันไม่เหนื่อยที่จะ รีแฟกเตอร์ โค้ดเดิมซ้ำ ๆ
แยกจากเรื่อง migration เอง วิธีที่พวกเขาเลือกใช้นั้นน่าสนใจเป็นพิเศษ
docs/PORTING.mdที่ลิงก์ไว้มีราว 300 กฎสำหรับการพอร์ต ซึ่งดูมากเกินกว่าที่ LLM ตัวไหนจะ “จำ” และทำตามได้ครบอย่างเคร่งครัดเนื่องจาก Anthropic เป็นเจ้าของ Bun การพอร์ตนี้จึงแทบจะมีงบโทเค็นไม่จำกัด และอาจถึงขั้นปล่อยเอเจนต์จำนวน
จำนวนไฟล์ * จำนวนกฎเพื่อพยายาม “รับประกัน” ว่าทำตามครบทุกข้อนอกจากนี้ยังแบ่งการพอร์ตเป็นสองขั้น: A คือพอร์ตแต่ละไฟล์แบบแยกขาดจากกันอย่างหยาบ ๆ โดยคาดว่า compile จะพัง ส่วน B คือเชื่อมทุกอย่างเข้าด้วยกันให้ compile ได้
ใน phase A จะบอกเอเจนต์ว่าโค้ด “ไม่จำเป็นต้อง compile ได้” และให้ให้คะแนนไฟล์ที่พอร์ตแล้วตามคุณภาพผลลัพธ์เป็น ต่ำ/กลาง/สูง
ต่ำคือ logic ผิด กลางคือ logic ถูกแต่ compile ไม่ได้ สูงคือ logic ถูกและน่าจะ compile ได้ด้วย
สิ่งนี้ตรงข้ามกับแนวทาง coding agent ที่ฉันเข้าใจและใช้อยู่โดยสิ้นเชิง เลยอยากรู้ผลว่าจะออกมาอย่างไร
ตามสัญชาตญาณของฉัน ถ้าบอกว่าไม่จำเป็นต้อง compile และไม่ได้ให้ “เป้าหมายปลายทาง” ที่ชัดเจน ผลลัพธ์จะคาดเดาได้ยากมาก และใน phase B ก็คงต้องมานั่งรีวิวกองโค้ดที่เชื่อถือไม่ได้มหาศาล
ลอง grep เร็ว ๆ พบว่าในคะแนนคุณภาพผลลัพธ์ 1279 รายการแบบนี้ มีประมาณ 3% เป็นต่ำ, 80% เป็นกลาง, และ 17% เป็นสูง
PORTING.mdมีประมาณ 16k โทเค็น และโฟกัสกับงานหลักอยู่สำหรับ sub-agent ใหม่ ๆ นี่ไม่แย่เลย และอาจจะเหมาะด้วยซ้ำ
สงสัยว่าแท้จริงแล้วอยาก ย้ายไป Rust หรือแค่อยากทดสอบ LLM ของ Anthropic กันแน่
ถ้า Anthropic ย้าย Bun ซึ่งเป็นหนึ่งในโปรเจ็กต์ที่ดังที่สุดของ Zig ไปยังภาษาอื่น ก็จะเป็นการแสดงแสนยานุภาพที่ค่อนข้างโจ่งแจ้ง
แน่นอนว่าฉันไม่ได้เชื่อสมมติฐานเชิงดราม่านี้เต็มร้อย แต่อาจเป็นแค่การใช้เงินหนา ๆ ของ Anthropic เพื่อโชว์ผลิตภัณฑ์ก็ได้
ดูน่าสนใจทีเดียว
ชุดกฎที่ต้องจัดการพร้อมกันในครั้งเดียวนั้นดูเหมือนจะตรวจสอบไม่ได้หากไม่ผ่านรอบ code review จำนวนมหาศาล
ถึงจะมีโทเค็นมาก แต่หลังการแปลงแบบนี้ดูเหมือนว่าโค้ดจะตรวจสอบได้ยากมากในทางปฏิบัติ
ถ้าแม้แต่ test ก็ต้องผ่านกระบวนการเดียวกัน ก็ชวนสงสัยว่าอะไรจะยังเหลือเป็น มาตรฐานตัดสินความจริง อยู่
ถึงอย่างนั้น ในฐานะการทดลองก็ถือว่ายิ่งใหญ่มาก
ถ้ามองว่าเหล่า Node.js killer เป็นอย่างไรบ้าง Deno ก็ให้การปรับปรุงเล็ก ๆ อย่างระบบสิทธิ์หรือการรองรับ TypeScript แบบ built-in แต่ก็ไม่ได้เขย่าโลก และฟีเจอร์เหล่านี้ก็กำลังถูกนำกลับเข้า Node.js
จากที่เคยใช้ ประสบการณ์นักพัฒนาไม่ได้ดีกว่าอย่างมีนัยสำคัญ และบางกรณีกลับแย่ลงเพราะมีเครื่องมือดี ๆ อย่าง pnpm อยู่แล้ว
มันอาจเร็วกว่า แต่ตลอด 5~6 ปีที่ผ่านมา ในขอบเขตการใช้งานของฉันก็แทบไม่เคยรู้สึกว่า Node.js มีปัญหาด้านประสิทธิภาพ
JSR ก็ไม่ได้เขย่าโลกเช่นกัน และชุมชนกลับไปสร้าง npmx ที่มอบประสบการณ์ดีกว่า now แทน
อย่างไรก็ดี standard library ของ Deno เช่น
@std/collectionsค่อนข้างดีจนฉันใช้อยู่ส่วน Bun นั้นมีขอบเขตกว้างเกินไปจนมีสัญญาณอันตรายหลายอย่างตั้งแต่แรก แต่ฉันก็ยังมองโลกในแง่ดีอย่างระมัดระวัง เพราะดูเหมือน Jarred ตั้งใจจะสร้าง JS runtime อเนกประสงค์ที่ดีที่สุดให้ได้ แม้จะต้องใช้เวลาหลายปี
แต่พอถูก Anthropic เข้าซื้อ และเห็นว่า Jarred ตอนนี้ทำ ~~vibe coding~~ การพัฒนาแบบใช้เอเจนต์ อยู่พอสมควร รวมถึงข่าวการ vibe porting ครั้งนี้ ต่อให้เป็น branch ทดลองก็ยิ่งทำให้ฉันมั่นใจว่าไม่ใช่โปรเจ็กต์ที่ฉันจะใช้
เพราะงั้น Node.js ก็ยังครองอยู่
พูดกันจริง ๆ ความสามารถ TypeScript แบบ built-in และ SQLite นั้นยอดเยี่ยมมาก
ฉันไม่ได้ต่อต้าน AI ไปเสียหมด และคิดว่าการ vibe coding ด้วยสคริปต์ Python เล็ก ๆ หรือเว็บแอปเพื่อแก้ปัญหาเฉพาะจุดนั้นทั้งสนุกและมีประโยชน์
แต่สำหรับโปรเจ็กต์ซับซ้อนที่มีส่วนประกอบเคลื่อนไหวมากและมีผู้ใช้จริง ฉันยิ่งมั่นใจซ้ำแล้วซ้ำเล่าว่าการ “พัฒนาแบบใช้เอเจนต์” ในวงกว้างนั้น ต่อให้เร่งการทำฟีเจอร์ได้ชั่วคราว สุดท้ายก็เป็น ผลขาดทุนสุทธิ ที่ทำให้โปรเจ็กต์เปราะบางและบวมขึ้น
ตัวอย่างที่นึกออกคือ VSCode, Cursor, mise, Perplexity web UI
แค่ทำ JS dropdown อันหนึ่งให้เลื่อนแล้วไม่กระตุก มันยากขนาดนั้นเลยหรือ
ฉันหวังว่าเครื่องมือ ไลบรารี และโปรเจ็กต์ขนาดใหญ่ที่ฉันพึ่งพาจะมองเห็นเรื่องนี้และใช้นโยบายต่อต้าน AI ที่เข้มงวดขึ้น
เพราะมันกดดันให้ Node ดีขึ้น
เมื่อก่อน Node ถึงขั้นจงใจไม่ implement btoa
แต่สุดท้ายทั้งคู่ก็น่าจะเหลือเป็น เชิงอรรถ
นี่เป็นทิศทางที่ผิดอย่างแท้จริง
ฉันยังไม่เคยเห็น ผู้ดูแล Rust สักคนที่ดูแลโปรเจ็กต์ Rust ขนาดกลาง คือระดับหลายแสนบรรทัดขึ้นไป แล้วพอใจกับ scalability ใน codebase ขนาดใหญ่
ฉันมองว่า Rust ยอดเยี่ยมเป็นพิเศษสำหรับ codebase ขนาดใหญ่:
https://matklad.github.io/2023/03/28/rust-is-a-scalable-language.html
https://ferrous-systems.com/blog/rust-as-productive-as-kotlin/
เพียงแต่ถ้าจะใช้ให้มีประสิทธิภาพ ก็ต้องรู้พอสมควรว่าตัวเองกำลังทำอะไรอยู่:
https://matklad.github.io/2021/09/05/Rust100k.html
ในบริบทนี้ฉันไม่ค่อยรู้ว่า Zig เป็นอย่างไรเมื่อเทียบกับ Rust
TigerBeetle มีวิธีออกแบบที่ค่อนข้างเฉพาะตัว
และยังรู้จักตัวอย่างบางส่วนที่โปรแกรม Rust 20k บรรทัดสามารถทำฟังก์ชันหลักของโปรแกรม Go 300k บรรทัดได้
ดังนั้นจึงไม่ตรงตามเงื่อนไขที่พูดไว้เป๊ะ ๆ
แต่ในช่วง 10k~100k บรรทัด ฉันพอใจกับ Rust มากในฐานะผู้ดูแล
ขนาดประมาณนี้เล็กพอที่โปรแกรมจะยังโฟกัสชัด แต่ก็ใหญ่พอจะสานแนวคิดหลักหนึ่งอย่างได้อย่างเต็มที่
ในระดับนี้ ทั้งตัวภาษาและเครื่องมือเป็นทรัพย์สินชั้นดีมาก อย่างน้อยก็ในประสบการณ์ส่วนตัวของฉัน
cargo-nextestตอนนี้มี โค้ด Rust 84k บรรทัด ถ้าไม่นับคอมเมนต์และบรรทัดว่าง และในฐานะผู้ดูแลคนเดียว ฉันมองว่าเป็นไปไม่ได้เลยที่จะเขียนมันด้วยภาษาอื่นให้ได้ตามมาตรฐานคุณภาพส่วนตัวของฉันอาจเป็นเพราะสิ่งนี้ก็ได้: https://github.com/oven-sh/bun/issues/28001
นี่ไม่ใช่ปัญหา memory safety เชิงเวลา อย่างตรงตัว