- Dự án trình duyệt Ladybird đã chọn Rust làm ngôn ngữ an toàn bộ nhớ để thay thế C++ và sử dụng các công cụ AI trong quá trình chuyển đổi
- Trước đó dự án từng xem xét Swift, nhưng do hạn chế về khả năng tương tác với C++ và ràng buộc nền tảng nên đã chuyển hướng sang Rust
- Mục tiêu port đầu tiên là engine JavaScript LibJS, với quá trình dịch được điều phối thủ công bằng hàng trăm prompt thông qua Claude Code và Codex
- Chỉ trong khoảng 2 tuần đã hoàn thành 25.000 dòng mã Rust, đồng thời xác minh rằng đầu ra và hiệu năng đều hoàn toàn giống phiên bản C++
- Trong thời gian tới, dự án sẽ tiếp tục duy trì mô hình phát triển song song C++ và Rust, đồng thời về dài hạn hướng tới tăng cường độ an toàn và khả năng bảo trì
Bối cảnh chọn Rust
- Ladybird đã xem xét nhiều ngôn ngữ để tìm một ngôn ngữ an toàn bộ nhớ thay thế C++
- Swift bị loại do thiếu khả năng tương tác với C++ và hạn chế hỗ trợ nền tảng ngoài hệ sinh thái Apple
- Rust được đánh giá là có hệ sinh thái lập trình hệ thống đã trưởng thành và nhiều người đóng góp đã quen thuộc với ngôn ngữ này
- Năm 2024, dự án từng hoãn áp dụng Rust vì không phù hợp với phong cách OOP kiểu C++, nhưng sau đó quyết định đưa trở lại nhờ tính an toàn và độ trưởng thành của hệ sinh thái
- Dự án tham khảo việc Firefox và Chromium đã triển khai Rust, từ đó đánh giá Rust cũng phù hợp với Ladybird
Quá trình port LibJS
- Mục tiêu chuyển đổi đầu tiên là LibJS, engine JavaScript của Ladybird
- Các thành phần độc lập như lexer, parser, AST, bytecode generator cùng với độ bao phủ kiểm thử dựa trên test262 khiến đây trở thành điểm khởi đầu phù hợp
- Quá trình port sử dụng Claude Code và OpenAI Codex
- Đây không phải tạo sinh tự động mà là dịch mã do con người dẫn dắt, với thứ tự port và cấu trúc mã do con người trực tiếp quyết định
- Dự án đưa ra chỉ dẫn chi tiết bằng hàng trăm prompt, sau đó dùng nhiều mô hình khác nhau để kiểm tra mã và phát hiện lỗi
Kết quả và kiểm chứng
- Mục tiêu là đầu ra của pipeline C++ và Rust phải giống nhau tới từng byte
- Khoảng 25.000 dòng mã Rust đã được hoàn thành trong 2 tuần, rút ngắn một công việc lẽ ra mất nhiều tháng
- AST và bytecode hoàn toàn giống nhau, đồng thời không có suy giảm hiệu năng trong kiểm thử và benchmark JavaScript
- Dự án dùng kiểm thử lockstep chạy đồng thời pipeline C++ và Rust để xác minh kết quả có khớp nhau trong quá trình duyệt web hay không
- Hiện tại mã nguồn vẫn giữ nguyên dạng được dịch từ C++, thậm chí mô phỏng cả mẫu phân bổ thanh ghi giống hệt
- Lý do là ưu tiên cao nhất hiện nay là đảm bảo tương thích với pipeline C++
- Trong tương lai, khi pipeline C++ bị loại bỏ, dự án sẽ đơn giản hóa và dọn dẹp mã Rust
Kế hoạch sắp tới
- Việc chuyển sang Rust được tiến hành như một công việc song song, không phải hướng phát triển chính duy nhất của dự án
- Mã C++ và Rust sẽ cùng tồn tại, với ranh giới tương tác rõ ràng
- Nhóm nòng cốt quản lý thứ tự và phạm vi port, còn người đóng góp bên ngoài cần phối hợp trước
- Về dài hạn, dự án sẽ thúc đẩy chuyển đổi dần dần với mục tiêu nâng cao độ an toàn và khả năng bảo trì
- Dù thừa nhận quyết định này có thể gây tranh cãi, dự án vẫn đánh giá đây là lựa chọn đúng đắn cho tương lai của Ladybird
1 bình luận
Ý kiến Hacker News
Điểm thông minh nhất của dự án này là yêu cầu đầu ra giống hệt từng byte
Nhờ vậy có thể chạy song song pipeline cũ và pipeline mới để so sánh diff, đồng thời bắt ngay các lỗi phát sinh trong lúc chuyển đổi
Nhiều dự án rewrite thất bại vì mọi người cố “cải thiện” trong lúc port, rồi cuối cùng phải đuổi theo các lỗi ma sinh ra từ khác biệt giữa bản cũ, bản mới, hoặc chỉ là khác biệt hành vi đơn thuần
Bản dịch từ C++ sang Rust ban đầu có hơi gượng gạo cũng không sao. Sau này khi phía C++ được loại bỏ hoàn toàn thì có thể dần dần chỉnh lại cho idiomatic hơn
Miễn là đầu ra vẫn giữ nguyên, bạn có thể refactor, tối ưu hóa, tài liệu hóa
Tôi nghĩ lúc đọc code để tài liệu hóa chính là thời điểm tốt nhất. Với một dự án phổ biến như Ladybird, tài liệu tốt cũng là cách tăng tốc phát triển
Trước đây chi phí migration quá lớn nên người ta hay tự biện minh kiểu “đã làm thì tiện cải tiến luôn”, nhưng rốt cuộc lại phải đuổi theo nhiều lỗi ma hơn
Họ dùng Claude Code và Codex để dịch code C++ sang Rust
Không phải hoàn toàn tự động mà có con người trực tiếp định hướng và tinh chỉnh bằng hàng trăm prompt nhỏ
Họ đặt yêu cầu từ đầu là đầu ra của hai pipeline phải giống hệt từng byte, và kết quả là hoàn thành 25.000 dòng code Rust chỉ trong 2 tuần
AST và bytecode đều khớp nhau, đồng thời đạt 0 regression
Tôi nghĩ đây mới là cách đúng để dùng AI cho việc port code giữa các ngôn ngữ
Chỉ trong 80 phút nó đã phân tích cấu trúc Drupal, khôi phục nguyên thiết kế và cấu trúc module, thậm chí còn triển khai cả plugin tùy chỉnh
Giờ nghe nói site đó đã được chuyển qua WordPress, ProcessWire, Node.js, và bây giờ còn sang cả Next.js
Tôi không muốn “một prompt ra code hoàn chỉnh”, mà muốn một công cụ giúp khuếch đại trí tuệ con người (IA) thông qua những phiên làm việc dài với AI
Nhưng có lẽ thị trường cho kiểu công cụ này nhỏ vì chỉ người có kiến thức phát triển phần mềm mới dùng được
Claude không trực tiếp viết code mà chỉ đưa gợi ý và review
Rust vốn là ngôn ngữ khó viết kiểu ngẫu hứng, nên cách này làm tôi rất hài lòng
Giờ còn có cả phiên bản wasm chạy được trong trình duyệt
Phần liên quan đến mật mã tôi không để nó tự triển khai, nên không cần lo chuyện đó
Tin chuyển sang Rust khá thú vị, nhưng cũng bất ngờ vì trước đây đội Ladybird từng có xu hướng khá “anti-Rust hype”
Dù vậy, nếu chuyển sang Rust thì có lẽ tôi sẽ dễ đóng góp hơn nhiều
Ngôn ngữ chỉ là công cụ, tôi không nghĩ cần phải gắn bản sắc cá nhân với một ngôn ngữ cụ thể
Andreas là một kỹ sư xuất sắc và cũng có nhạy cảm kinh doanh
Việc anh ấy phát triển một dự án sở thích thành dự án mang tầm công nghiệp rất ấn tượng
Nhưng những lần chuyển ngôn ngữ nhanh như vậy vẫn tạo cảm giác hơi bất an
Tôi xem đây là kết quả của việc dự án phát triển một cách tự nhiên
Câu kiểu “code Rust không chuẩn lắm nhưng sẽ dọn dẹp sau” khiến tôi lo rằng nó đang ám chỉ một đợt rewrite khác
Việc startup đổi ngôn ngữ thường bị xem như tín hiệu rủi ro
Khi vừa phát triển bản mới vừa duy trì tính năng cho bản cũ, sẽ nảy sinh một cuộc đua tốc độ, và bản mới có thể không bao giờ bắt kịp
Linux, PHP và musl libc cũng từng trải qua nhiều lần rewrite toàn phần
Giờ AI đã phổ biến, cách tính toán cho chuyện “rewrite toàn bộ bằng ngôn ngữ mới” đã khác hẳn
Đặc biệt nếu có test suite thì rủi ro giảm đi rất nhiều
Đây là thời đại mà tầm quan trọng của test đã tăng lên gấp 10 lần
Có thể nhanh chóng thử nhiều UI như Streamlit, Shiny, Dash nên việc prototyping rất vui
Ngay bây giờ, với một số dự án thì tổ hợp low-code + agent đã đủ để vận hành
Đoạn “giao code review cho AI” nghe có phần đáng lo
Mô hình vẫn có giới hạn trong việc phát hiện lỗi logic
Tuy nhiên, vấn đề then chốt là liệu việc “dọn dẹp (cleanup)” có thực sự được làm về sau hay không
Nếu phụ thuộc vào code AI thì sẽ tạo ra vòng luẩn quẩn với mức phụ thuộc vào AI ngày càng cao
Việc dự án phát triển song song cả C++ và Rust trông khá kém hiệu quả
Tôi nghĩ tốt hơn là thống nhất về một ngôn ngữ an toàn bộ nhớ
Miễn là từng component chỉ được viết bằng một ngôn ngữ thì không sao
Khi chấp nhận Swift vào năm 2024, Andreas từng có tweet về Rust
Anh ấy nói Rust rất tuyệt cho các chương trình chạy ngắn hạn, nhưng lại bất tiện với các chương trình chạy lâu và duy trì đồ thị đối tượng phức tạp
Anh ấy cũng nói cộng đồng có phần độc hại
Liên kết tweet liên quan
Tôi tò mò liệu code Rust phi chuẩn có trở thành nợ kỹ thuật về sau hay không
Dự án Servo cũng từng gặp vấn đề như vậy, nhưng trong quá trình đó họ cũng bắt được các lỗi tiềm ẩn
Việc chuyển sang Rust có vẻ là một lựa chọn chín chắn phù hợp với triết lý đó