- Tính năng comptime của Zig cung cấp khả năng đánh giá mạnh mẽ tại thời điểm biên dịch nhưng bị giới hạn có chủ đích
- Khi thực thi mã ở thời điểm biên dịch, không thể truy cập thông tin của host, một thiết kế phù hợp cho cross-compilation
- Không hỗ trợ sinh mã động, DSL, RTTI, I/O..., thay vào đó dùng chuyên biệt hóa mã dựa trên kiểu một cách tường minh
- RTTI có thể tự triển khai, tức có thể tái cấu trúc thông tin kiểu vốn chỉ tồn tại ở thời điểm biên dịch để dùng được lúc chạy
- Có thể tạo kiểu mới bằng comptime nhưng không thể mở rộng API, không thể thêm method do người dùng định nghĩa
Những điều comptime của Zig không làm
comptime của Zig dù cung cấp các khả năng mạnh như generic, biên dịch có điều kiện, serialization, ORM, v.v. nhưng một số tính năng vẫn bị giới hạn một cách tường minh
- Chính những giới hạn đó lại khiến thiết kế của Zig trở nên ngắn gọn và dễ dự đoán hơn
-
Không truy cập được thông tin host (No Host Leakage)
- Mã
comptime hoạt động dựa trên nền tảng đích chứ không phải hệ thống đang chạy đoạn mã đó
- Trong Zig, ở thời điểm biên dịch không thể dùng thông tin như endianness hay kích thước con trỏ của hệ thống host
- Mục đích là đảm bảo an toàn khi xét tới cross-compilation
- Trong ví dụ mã, kết quả xuất byte của số ở định dạng BF16 thay đổi theo nền tảng đích
-
Không có sinh mã dựa trên chuỗi (No #eval)
- Zig không cung cấp khả năng sinh mã động như
#include của C, mixin của ngôn ngữ D hay macro của Rust
- Thay vào đó, nó hỗ trợ đánh giá từng phần (partial evaluation) dựa trên đối số
comptime
- Nếu một đối số nhất định đã được biết tại thời điểm biên dịch, chỉ nhánh tương ứng sẽ được giữ lại, nhờ đó có thể tối ưu hóa mã
-
Không thể mở rộng cú pháp DSL (No DSLs)
- Trong Zig không có khả năng tạo cú pháp do người dùng định nghĩa như trong Lisp hay Rust
- Mọi dữ liệu chỉ có thể được truyền dưới dạng giá trị (value) theo cú pháp của Zig
- Những DSL bị giới hạn như chuỗi định dạng (
printf) chỉ có thể được triển khai bằng chuỗi comptime
-
Không có thông tin kiểu lúc chạy (No RTTI)
- Zig có thể hoạt động giống ngôn ngữ động như Python, nhưng thông tin kiểu chỉ tồn tại ở
comptime
- Nếu muốn dùng cả ở runtime thì phải tự định nghĩa struct RTTI và thao tác bằng con trỏ
- Ví dụ: định nghĩa struct
RTTI chứa tên trường và thông tin offset của các field, rồi truy cập field bằng con trỏ
-
Không thể tạo API mới (No New API)
- Trong Zig có thể tạo kiểu mới bằng
comptime, nhưng không thể thêm method vào kiểu đó
- Không thể mở rộng API như derive macro của Rust
- Khi triển khai JSON serialization, không thể thêm method
.to_json(), mà phải truyền đối số kiểu cho một hàm toàn cục để triển khai
-
Không có IO ở thời điểm biên dịch (No IO)
comptime của Zig cấm truy cập tài nguyên bên ngoài như hệ thống tệp, mạng hay cơ sở dữ liệu
- Nhờ vậy, tính tái lập, độ an toàn và khả năng tận dụng cache được nâng cao
- Nếu cần IO, có thể dùng hệ thống build là
build.zig để import mã Zig đã được sinh trước
-
Tổng kết: El Disco (cân bằng giữa trừu tượng hóa và tính đơn giản)
- Zig cung cấp khả năng metaprogramming mạnh mẽ nhưng vẫn giữ được tính dễ dự đoán nhờ thiết kế rất hạn chế
- Nhờ các giới hạn này,
comptime của Zig vẫn thực dụng và dễ hiểu
- Dù không có các lớp trừu tượng phức tạp, nó vẫn hữu ích trong thực tế và chỉ vận hành rõ ràng đúng theo những gì được khai báo
1 bình luận
Ý kiến trên Hacker News
comptimecủa Zig có những đặc điểm độc đáoNhược điểm của
comptimetrong Zig và cách giải quyếtzig build, sau đó dùng@importđể biên dịchCụm tiếng Tây Ban Nha được trích từ truyện của Borges nói về một vị thần Bắc Âu
Tính linh hoạt của
comptimeĐiểm nổi tiếng của tính năng
comptimetrong ZigMột bài viết blog mang tính giáo dục
comptime forvàinline forcomptimeÝ kiến tích cực về ngôn ngữ và công cụ Zig
Những điểm thú vị về
comptimecủa ZigSự bối rối về việc thực thi mã tại thời điểm biên dịch