- Theo hướng tách
build.zigvà hệ thống build thành các tiến trình riêng biệt, Zig đã chuyển logic quản lý gói sang tiến trình maker nằm ngoài tệp thực thi trình biên dịch zig build,zig fetch,zig init,zig libcđược chuyển sang phía maker, nên mã xử lý HTTP, TLS, Git, nén vàbuild.zig.zonđược phân phối dưới dạng mã nguồn- Với cấu trúc này, có thể sửa chức năng quản lý gói mà không cần build lại trình biên dịch, đồng thời maker được biên dịch với
ReleaseSafenên kiểm tra an toàn cho các tác vụ mạng cũng được bật - Mục đích ban đầu là giải quyết vấn đề thay đổi
--build-runnertừng chặn ZLS bằng cách phơi bày build server protocol, và trong cây tiến trình mới, maker vẫn là tiến trình cha của configurer nên có thể xử lý việc chạy lại cấu hình ổn định hơn - Tác động với người dùng không lớn, nhưng tệp thực thi Zig giảm từ 14.1MiB xuống 13.5MiB, tức giảm 4%, còn
--maker-optvà--zig-lib-dirlần lượt được thay bằng biến môi trườngZIG_DEBUG_MAKER,ZIG_LIB_DIR
Di chuyển logic quản lý gói
- Sau khi Zig tách script
build.zigcủa người dùng và chính hệ thống build thành các tiến trình riêng, cấu trúc này cũng được thay đổi để đặt logic quản lý gói về phía hệ thống build - Các lệnh con được chuyển sang tiến trình maker gồm:
zig buildzig fetchzig initzig libc
Phần mã được loại khỏi tệp thực thi trình biên dịch
- Những vùng mã lớn trước đây nằm trong tệp thực thi trình biên dịch nay được phân phối dưới dạng mã nguồn
- logic lấy gói
- HTTP client và networking
- TLS và mã hóa liên quan
- giao thức Git
xz,gzip,zstd,flate,zip- phân tích cú pháp, kiểm tra hợp lệ và các xử lý khác của tệp
build.zig.zon
- Các chức năng này có thể được vá mà không cần build lại trình biên dịch, giúp người dùng và cộng tác viên thử nghiệm dễ hơn
- Tệp thực thi maker được biên dịch ở chế độ
ReleaseSafe, nên kiểm tra an toàn trong các tác vụ mạng của quản lý gói được bật - Mã mật mã dùng cho networking và băm tệp có thể tận dụng các lệnh CPU chuyên dụng có trên máy chủ
Cấu trúc tiến trình và build server
- Động lực ban đầu là giải quyết vấn đề từng chặn ZLS bằng cách phơi bày build server protocol
- Ở cấu trúc cũ,
zig buildvừa đảm nhiệm trình biên dịch vừa đảm nhiệm trình quản lý gói, còn builder bên dưới chứa logicbuild.zigcủa người dùng và phần triển khai hệ thống build - Sau khi tách maker/configurer, cấu trúc là:
zig build: trình biên dịch + trình quản lý góiconfigurer: logicbuild.zigcủa người dùngmaker: hệ thống build
- Trong cấu trúc này,
zig build --watchchạy lâu phải chạy lại configurer khi phát hiện thay đổi ởbuild.zighoặc các tệp liên quan, và để làm vậy thì maker phải thoát đểzig buildcó cơ hội lặp lại logic quản lý gói - Trong cấu trúc mới,
zig buildchỉ còn đảm nhiệm trình biên dịch, còn maker phía dưới phụ trách hệ thống build và trình quản lý gói, với configurer là tiến trình con của maker - Ngay cả khi cần chạy lại cấu hình, maker vẫn có thể tiếp tục tồn tại như tiến trình cha
- Với build server được lên kế hoạch, thay vì để client kết nối lại sau khi server kết thúc, sẽ có thể áp dụng cấu trúc thông báo thay đổi cấu hình cho client
Các thay đổi có thể quan sát được
- Phần lớn không phải thay đổi phá vỡ tương thích, nhưng vẫn có một số khác biệt người dùng có thể thấy
- Kích thước binary của tệp thực thi Zig: theo chuẩn
ReleaseSmallkhông có LLVM, giảm từ 14.1MiB xuống 13.5MiB, tức giảm 4% - Cờ
--maker-optđược thay bằng biến môi trườngZIG_DEBUG_MAKER - Cờ
--zig-lib-dirđược thay bằng biến môi trườngZIG_LIB_DIR
- Kích thước binary của tệp thực thi Zig: theo chuẩn
Các issue chặn còn lại trước Zig 0.17.0
- Sau loạt thay đổi này, các issue chặn chính còn lại sẽ là những việc trọng tâm trước khi gắn thẻ Zig 0.17.0
- Trong tháng 7 có hai hội nghị và phần chuẩn bị bài thuyết trình, nên thời điểm thực tế để hoàn tất các việc này được dự đoán là đầu tháng 8
- Techatrix của nhóm ZLS đã liên hệ và hợp tác về công việc build server protocol, đồng thời đang tìm tài trợ
1 bình luận
Các ý kiến trên Hacker News
Các nhà phát triển Zig, Go, Python thỉnh thoảng thông báo rằng họ đã loại bỏ chất làm mát khỏi bình nhiên liệu, và những người ủng hộ thì hoan hô rằng điều đó tốt cho ngôn ngữ và hiệu năng cũng sẽ được cải thiện đáng kể
Nhưng điều tôi tò mò hơn là ngay từ đầu vì sao chất làm mát lại được cho vào bình nhiên liệu
Đưa quản lý gói vào trong compiler thì tiện, nhưng khi ngôn ngữ và công cụ bắt đầu được dùng rộng rãi, tính năng từng có lợi cho cá nhân lại trở thành món nợ cản trở việc áp dụng
Trong nhiều dự án, các nhà phát triển chọn cách tiện lợi để tránh “những việc khó cần làm nếu muốn làm cho đúng”, và vì người khác cũng không muốn làm việc khó đó, nó trở thành thông lệ
Nếu triển khai trình quản lý gói trong build system nhưng cũng muốn giữ nó trong compiler, trước hết phải quyết định sẽ đặt lớp trừu tượng nào giữa compiler và build system
Điều này cũng ảnh hưởng đến import system và các phần nền tảng của ngôn ngữ; những phần này cần được thiết kế đúng và cũng khó thay đổi về sau
Ban đầu có thể ghép chặt quản lý gói với compiler, thiết kế ngược từ trải nghiệm lập trình viên mong muốn, rồi sau đó thay đổi phần triển khai thì tác động lên người dùng có thể ít hơn
Đặc biệt, tôi thấy import system của Python đã trở nên rất phức tạp và nhiều khiếm khuyết vì phải dung nạp việc quản lý gói được thực hiện theo nhiều cách
Ngược lại, Go được thiết kế với quản lý gói trong đầu ngay từ đầu, nên cú pháp liên quan đến import tương đối nhỏ gọn và sạch sẽ. Tất nhiên không phải quyết định thiết kế nào tôi cũng đồng ý
Ngay cả một sản phẩm nhỏ cũng khó dự đoán các thành phần sẽ tương tác với nhau thế nào, nên cứ phải sửa liên tục
Giờ hãy thử nghĩ đến việc tạo ra một ngôn ngữ thay thế C tự host
Tốc độ cải thiện càng lớn thì càng được hoan hô, nhưng phần lớn tối ưu hóa không phải là kỹ thuật thông minh, mà là dùng profiler để tìm ra “ơ, chất làm mát không nên nằm trong bình nhiên liệu”
Phần lớn nút thắt hiệu năng không phải là giới hạn bản chất của phần cứng hay của chính bài toán
Có một lượng công việc tối thiểu cần thiết để có kết quả, nhưng lý do ứng dụng chậm hầu như luôn là đống tạp nham được đắp thêm lên trên
Quá trình phát triển Zig thật sự cho cảm giác có bầu không khí lành mạnh
Tôi dùng LLM hằng ngày và thừa nhận nó làm tốt đến mức đáng ngạc nhiên ở nhiều loại vấn đề, nhưng tôi không muốn một ngôn ngữ lập trình do LLM tạo ra
Mọi dòng code, quyết định và đánh đổi trong một ngôn ngữ lập trình đều quan trọng
Một ngôn ngữ được thiết kế và code chỉ dựa trên cảm giác bầu không khí sẽ là thảm họa
Chưa có mô hình nào từng cho tôi thấy code đủ thuyết phục để tin điều ngược lại. Ngay cả Fable, dù rõ ràng tốt hơn các mô hình tốt nhất trước đó, cũng vậy
Mô hình không có mong muốn, không có quan điểm có ý nghĩa, và không biết điều gì tạo cảm giác thoải mái hay khó chịu trong một ngôn ngữ. Với các giao diện GUI hay CLI đủ phức tạp cũng như vậy
Một ngôn ngữ như Zig không thể xuất phát từ LLM, trừ khi chỉ đơn giản là sao chép Zig; mà kể cả sao chép thì cũng sẽ là một bản sao tệ hơn
Ở đây, sao chép bằng LLM không có nghĩa là
cpnguyên văn cây mã nguồn, mà là kiểu LLM viết đặc tả rồi một LLM khác triển khai ngôn ngữ theo đặc tả đóTôi đã làm bootloader và làm việc với UEFI, và với cá nhân tôi thì dễ hơn nhiều so với khi làm bằng C
Tuy vậy cũng có phần thiên lệch vì có niềm vui khi học thứ mới mẻ, bóng bẩy
Tôi tự hỏi đây có phải là thay đổi đã khiến Zig loại bỏ
@cImportvà chuyển nó sang build system khôngThuần túy là vấn đề trải nghiệm người dùng, và tôi hiểu việc tách build system khỏi compiler là quan trọng với maintainer, nhưng vẫn hơi tiếc khi độ ổn định phát triển lại được đặt trước trải nghiệm người dùng
Đó là quyết định đúng, nhưng buồn; tôi nghĩ
@cImporttừng là một tính năng sát thủ mạnh mẽ của ngôn ngữ nàyThay đổi này liên quan đến code tải xuống và giải nén các gói bên thứ ba
Thay đổi
@cImportlà một phần của nỗ lực nhằm một ngày nào đó biến phụ thuộc LLVM/libclang của Zig thành tùy chọn, rồi sau này có thể tách nó ra thành gói bên thứ ba, nhưng có vẻ không liên quan trực tiếpTôi đọc ở đâu đó rằng mục tiêu dài hạn là chuyển build system vào trong WebAssembly VM
Nếu vậy thì thật ấn tượng
Đây là một thay đổi tốt cho Zig
Tôi khá muốn chuyển từ Go sang Zig, nhưng hiện tại chỉ đứng ngoài quan sát cũng thấy thú vị
Mỗi khi một ngôn ngữ tự tạo hệ thống gói riêng, tôi chỉ cảm thấy chúng ta đã bỏ lỡ một cơ hội lớn nào đó
Ngoại lệ duy nhất là C/C++, vì dù tốt hay xấu thì cũng chưa có thứ gì đủ vững chắc
Lựa chọn như vậy về sau có thể tạo ra quy trình rất phức tạp khi phải trộn nhiều ngôn ngữ
Hệ thống đóng gói giúp công việc dễ hơn, nhưng ngay khi phải dùng ngôn ngữ khác, các bước sau đó lại trở nên phức tạp hơn
Bạn muốn một build system duy nhất cho mọi ngôn ngữ à? Có những hệ thống như Bazel và chúng cũng thường được dùng cho dự án đa ngôn ngữ, nhưng trên thực tế có vẻ build system có kiến thức riêng theo từng ngôn ngữ đã chứng tỏ là dễ xử lý hơn nhiều
Vì nó buộc người ta phải suy nghĩ cẩn thận trước khi thêm dependency
Những dependency như vậy thường có chi phí ẩn như lỗ hổng bảo mật
Nhiều hệ thống quan trọng được viết bằng C++, nên việc dễ dàng phụ thuộc vào hàng chục gói bên thứ ba mà không audit đúng cách từng gói là quá rủi ro
Zig đang lấp vào khoảng trống đó
Thực tế gần như chỉ có Buck và Bazel là những build system như vậy, nhưng cả hai đều mang quá nhiều gánh nặng từ các tổ chức khổng lồ đứng sau
Thật đáng tiếc
Việc tách bạch các mối quan tâm được thực hiện rất thuyết phục