1 điểm bởi GN⁺ 2026-03-12 | 1 bình luận | Chia sẻ qua WhatsApp
  • Logic phân giải kiểu (type resolution) của trình biên dịch Zig đã được thiết kế lại toàn diện, giúp đơn giản hóa cấu trúc nội bộ và mang lại những cải thiện rõ rệt cho người dùng
  • Thiết kế mới trì hoãn (lazy) việc phân tích các trường của kiểu, nên không kiểm tra không cần thiết cấu trúc chi tiết của các kiểu chưa được khởi tạo
  • Thông báo lỗi vòng lặp phụ thuộc (dependency loop) đã được cải thiện cụ thể hơn, giúp xác định rõ nguyên nhân của vòng lặp
  • Vấn đề phân tích quá mức và nhiều lỗi trong tính năng biên dịch tăng dần (incremental compilation) đã được khắc phục, giúp tốc độ build cải thiện đáng kể
  • Thay đổi lần này bao gồm hàng chục bản sửa lỗi và các cải tiến ngôn ngữ nhỏ, qua đó nâng cao toàn diện hiệu năng và trải nghiệm phát triển của trình biên dịch Zig

Thiết kế lại logic phân giải kiểu

  • Một PR quy mô khoảng 30.000 dòng đã được hợp nhất, viết lại logic phân giải kiểu của trình biên dịch Zig theo cấu trúc logic và trực quan hơn
    • Trong quá trình này, cấu trúc nội bộ của trình biên dịch đã được sắp xếp lại, đồng thời người dùng cũng nhận được lợi ích cải thiện trực tiếp
  • Trình biên dịch được thay đổi để đánh giá lười việc phân tích trường của kiểu, nên không còn duyệt không cần thiết vào cấu trúc chi tiết của các kiểu chưa được khởi tạo
    • Trong mã ví dụ, khi một struct chứa trường @compileError chỉ được dùng như namespace, trước đây sẽ phát sinh lỗi biên dịch nhưng giờ đây có thể biên dịch bình thường
    • Điều này giúp tránh phụ thuộc mã không cần thiết khi sử dụng các kiểu dạng namespace như std.Io.Writer

Cải thiện thông báo lỗi vòng lặp phụ thuộc

  • Trước đây, thông báo lỗi vòng lặp phụ thuộc khá mơ hồ, nhưng nay đã hiển thị rõ nguyên nhân và vị trí của vòng lặp
    • Trong mã ví dụ, khi hai struct FooBar tham chiếu lẫn nhau, thông báo lỗi sẽ chỉ ra cụ thể vị trí phụ thuộc của từng kiểu
    • Thông báo bao gồm độ dài vòng lặp, vị trí khai báo từng trường, và vị trí truy vấn căn chỉnh
  • Ngay cả với các vòng lặp phức tạp, thông báo vẫn cung cấp đủ thông tin để dễ dàng xác định nguyên nhân vấn đề

Cải thiện hiệu năng biên dịch tăng dần

  • Thay đổi lần này đã sửa nhiều lỗi trong tính năng biên dịch tăng dần
    • Đặc biệt, vấn đề “phân tích quá mức (over-analysis)” đã được giải quyết, tối ưu để chỉ biên dịch lại những phần đã thay đổi
    • Kết quả là trong nhiều trường hợp, tốc độ biên dịch được cải thiện đáng kể
  • Nhà phát triển có thể bật biên dịch tăng dần trên Zig 0.15.1 trở lên để trải nghiệm quy trình phát triển được cải thiện

Các cải tiến khác

  • PR lần này bao gồm hàng chục bản sửa lỗi, thay đổi ngôn ngữ nhỏ, và cải thiện hiệu năng trình biên dịch
    • Phần lớn là các trường hợp chi tiết hoặc đặc thù
  • Có thể xem toàn bộ thay đổi trên Codeberg tại PR #31403
  • Khuyến khích báo cáo issue nếu phát hiện lỗi mới

Ý nghĩa của thay đổi

  • Việc đơn giản hóa logic phân giải kiểu và tối ưu biên dịch tăng dần đã tăng cường độ ổn định và hiệu quả của trình biên dịch Zig
  • Nhà phát triển sẽ nhận được phản hồi nhanh hơn và rõ ràng hơn, đồng thời có thể kỳ vọng nâng cao năng suất ngay cả với codebase quy mô lớn

1 bình luận

 
GN⁺ 2026-03-12
Ý kiến trên Hacker News
  • Tôi là tác giả của devlog này
    Tôi hiểu những lo ngại về việc phá vỡ khả năng tương thích do thay đổi ngôn ngữ, nhưng muốn nói rõ rằng thay đổi lần này của trình biên dịch không ở mức gây ảnh hưởng lớn
    Ví dụ, khi build ZLS bằng nhánh mới, tôi chỉ cần sửa kiểu thay .{} thành .empty. Đây là do việc loại bỏ giá trị mặc định của std.ArrayList, và nó đã ở trạng thái deprecated từ 1 năm trước
    Với dự án Awebo cũng vậy, trong toàn bộ cây phụ thuộc chỉ có ba chỗ cần sửa — đổi sang .empty, thêm comptime, và thêm orelse @alignOf(T)
    Phần lớn những chỉnh sửa này đều là thay đổi đơn giản ở mức mà hầu hết lập trình viên Zig sẽ xử lý gần như theo phản xạ
    Trọng tâm của PR lần này không phải là gây vỡ, mà là sửa lỗi và cải thiện biên dịch gia tăng

    • Tôi là một trong những người đã viết bình luận có vẻ khá phê phán về thay đổi này
      Tôi nghĩ chất lượng và mức độ chuẩn bị của PR là rất cao, hoàn toàn không có ý hạ thấp công sức của tác giả
      Chỉ là tôi rút ra bài học rằng sau này nên thêm nhiều chú thích hơn và để lại ý kiến cẩn trọng hơn
    • Tôi không trực tiếp tham gia Zig, nhưng khi thấy chú thích được thêm vào lib/std/multi_array_list.zig thì có một điều khiến tôi thắc mắc
      Tôi không hiểu vì sao việc dùng @alignOf(T) trong định nghĩa MultiArrayList(T) lại tạo ra phụ thuộc vòng
      T có là chính MultiArrayList thì đó chẳng phải vẫn là một kiểu monomorphic hoàn toàn tách biệt sao? Có lẽ tôi đang bỏ sót điều gì đó
      Mã liên quan: liên kết
  • Tôi tò mò về trải nghiệm của những người dùng Zig trong môi trường production
    Ngôn ngữ thay đổi thường xuyên, nên tôi muốn biết chu kỳ cập nhật hay rewrite thường ra sao, và liệu có trường hợp các gói phụ thuộc bị chậm hơn so với phiên bản ngôn ngữ hay không
    Tôi biết Bun đang tận dụng Zig rất tốt, nhưng cũng muốn nghe thêm các trường hợp khác

    • Tôi đang duy trì một codebase trình biên dịch Zig khoảng 250 nghìn LoC (roc-lang/roc)
      Trong 1~2 năm qua, các thay đổi của ngôn ngữ và thư viện chuẩn diễn ra không có vấn đề lớn
      Trước đây việc nâng cấp khá phiền, nhưng giờ chỉ còn cảm giác như “hơi bất tiện một chút
      Nếu ai hỏi về trải nghiệm dùng Zig, thì phần này ổn định đến mức tôi gần như còn không nhắc tới
    • Tôi từng làm trên hai codebase Zig production là tigerbeetlesig
      Những dự án lớn như vậy nâng cấp dựa trên các bản phát hành đã gắn thẻ, và thường hoàn tất migration trong vài ngày đến vài tuần
      Chúng cũng gần như không có phụ thuộc, nên gánh nặng nâng cấp không lớn
    • Zig 0.15 khá ổn định
      Tuy vậy, đôi khi chỉ một lỗi gõ nhỏ cũng có thể gây crash trình biên dịch SIGBUS, khiến việc debug rất khó
      .zig-cache từng phình tới 173GB, gây vấn đề trên VPS ARM
      Khi nâng lightpanda từ 0.14 lên 0.15 thì mọi thứ khá suôn sẻ. Có lẽ 0.16 cũng sẽ không có vấn đề lớn
      Nhưng với tư cách là người phát triển thư viện, tôi thấy khó theo kịp tốc độ thay đổi nhanh của 0.16
      Hiện tại tôi chỉ hỗ trợ thử nghiệm trên nhánh “dev”
    • Tôi đang chạy khoảng 20 nghìn LoC Zig 0.16 ở production trong chế độ DebugSafe
      Tôi đã rewrite một module Node.js/TypeScript sang Zig, và kết quả là nhanh gấp 2 lần, dùng ít hơn 70% bộ nhớ
      Hỗ trợ sqlite/serialize JSON của Zig rất mạnh, đó là một lợi thế lớn
      Điểm trừ là thiếu cú pháp closure hoặc vtable, nên khó tách lớp mã nguồn
      Tôi dùng Arcs và bộ cấp phát bumper để đảm bảo an toàn bộ nhớ, và dự định tiếp tục chạy ở DebugSafe
      Chuyển sang ReleaseFast có giúp tăng thêm 25% hiệu năng, nhưng chưa đáng để đánh đổi sự an toàn
    • Tôi nghĩ lời hứa tương thích ngược vĩnh viễn của C++ thực ra là một sai lầm đã kìm hãm sự phát triển của ngôn ngữ
      Dù phải sửa mã nguồn, về lâu dài đây vẫn là cách tiếp cận đúng đắn
  • Tôi rất ấn tượng với những gì đội ngũ Zig làm được
    Tôi hay dùng terminal ghostty viết bằng Zig, và nó rất ổn định
    Nhưng cá nhân tôi vẫn thích Rust hơn
    Rust chọn mô hình “thế giới đóng”, còn Zig chọn “thế giới mở”
    Rust yêu cầu implement trait một cách tường minh, trong khi Zig chỉ cần hình dạng (shape) của kiểu phù hợp là hoạt động
    Nhờ vậy Zig có thể metaprogramming rất mạnh, nhưng nhược điểm là suy luận kiểu thiếu rõ ràng nên autocomplete, tài liệu hóa, hỗ trợ LSP trở nên khó hơn

    • Tôi muốn nghe một ví dụ cụ thể
      Nghe mô tả thì khá giống interface của Go, nhưng tôi biết Zig dường như không có khái niệm tương ứng trực tiếp
  • Việc chuyển từ kernel32 sang Ntdll khá thú vị
    Đây là một ý tưởng cũng có thể áp dụng cho API user-space của Linux
    Đặc biệt là cách xử lý lỗi ở ranh giới kernel-user có nét tương đồng
    Tuy nhiên trên Linux thì libc và kernel gắn chặt với nhau nên việc dùng errno là bắt buộc
    Tôi tò mò vì sao trên Windows cũng xuất hiện kiểu mẫu này

    • Mẫu errno hay GetLastError()di sản từ thời trước khi có thread
      Ngày xưa lập lịch cộng tác khiến biến toàn cục vẫn an toàn, nhưng khi multicore và thread xuất hiện thì điều đó trở nên nguy hiểm
      Vì thế thread local đã xuất hiện như một phương án thay thế
  • Thay vì dùng kiểu như namespace, tôi nghĩ có lẽ tốt hơn là thêm namespace tường minh vào ngôn ngữ

    • Zig theo đuổi chủ nghĩa tối giản trong ngôn ngữ
      Nếu một tính năng tối ưu được ở nhiều nơi, thì đến lúc đó họ mới thêm vào theo cách tiếp cận này
    • Thực ra đây không phải cách lách luật mà là sự thanh lịch trong thiết kế
      Trong Zig, @import biến file thành một struct, còn namespace đơn giản được biểu diễn bằng struct lồng nhau
      Nói cách khác, namespace cũng chỉ là một import khác mà thôi
      (Tôi chưa tỉnh cà phê hẳn nên không dám đảm bảo chính xác tuyệt đối)
  • Có một điều thường bị bỏ qua trong các cuộc thảo luận về thay đổi ngôn ngữ — đó là tác động tới hệ sinh thái
    Nếu ngôn ngữ thường xuyên bị phá vỡ, thì không chỉ ứng dụng mà cả thư viện, công cụ, tutorial cũng phải liên tục chạy theo
    Kết quả là hệ sinh thái sẽ nghiêng về các dự án được bảo trì tích cực hơn là những thư viện “làm một lần rồi bỏ đó”
    Đây là một trade-off hợp lý ở giai đoạn thiết kế ngôn ngữ ban đầu, nhưng về lâu dài nó sẽ ảnh hưởng đến tăng trưởng của hệ sinh thái
    Nhiều ngôn ngữ mới khác đang đầu tư rất nhiều công sức để giảm thiểu sự mệt mỏi vì thay đổi này
    Sẽ rất thú vị khi theo dõi xem cách tiếp cận của Zig sẽ dẫn đến kết quả gì

    • Có thể lấy hệ sinh thái addon của Blender làm ví dụ
      Blender thường xuyên phá vỡ API, nhưng phần lớn chỉnh sửa đều nhỏ
      Tuy vậy vẫn phải có ai đó đi sửa, và nếu bảo trì bị ngưng thì người dùng sẽ phải tự vá lấy
      Addon trả phí có khả năng được duy trì cao hơn, nhưng điều đó cũng không được đảm bảo
    • Dù vậy tôi vẫn nghĩ Zig đáng để như thế
      Thư viện không được bảo trì thì đằng nào cũng là mã tệ
      Thay vì chỉ trích Zig, mong mọi người đừng tranh thủ quảng bá các ngôn ngữ khác (như C3)
  • Nội dung trong PR của Zig nói rằng “Chromium, boringssl, Firefox, Rust gọi SystemFunction036 của advapi32.dll” thực ra là không đúng
    Họ đã dùng ProcessPrng rồi, và từ Windows 10 trở đi nó không thất bại
    Cơ sở liên quan nằm trong whitepaper của Microsoft
    Cơ chế này được thiết kế để yêu cầu RNG tuyệt đối không thể thất bại, và nếu có lỗi thì chính tiến trình sẽ bị chấm dứt
    Nói cách khác, để đảm bảo số ngẫu nhiên chất lượng cao, nó không trả về mã lỗi

    • (Đây là trả lời cho một devlog khác trên cùng trang)
  • Ngữ nghĩa ngôn ngữ của Zig nhìn bề ngoài thì đơn giản, nhưng tương tác giữa các phần lại khá tinh tế
    Điều này khiến tôi nghĩ rằng theo thời gian nó có thể sinh ra những trường hợp góc cạnh phức tạp giống như các quy tắc template của C++

  • Một PR 30 nghìn dòng là thành tựu rất lớn
    Nhưng việc thay đổi ngữ nghĩa ngôn ngữ là chuyện cực kỳ hệ trọng, nên tôi khá bất ngờ
    Tôi hiểu Zig còn chưa tới 1.0 nên thay đổi nhanh, nhưng kiểu diễn đạt casual như “đã đổi ngữ nghĩa ở nhánh này” vẫn khiến tôi hơi sửng sốt
    Tôi tò mò không biết đây có phải văn hóa đặc trưng của Zig hay chỉ là tôi đã lạc hậu rồi
    Cụm “modern Zig” cũng khiến tôi bật cười vì tốc độ thay đổi quá nhanh của ngôn ngữ

    • Không nên vì văn phong casual mà xem đó là thái độ hời hợt
      Devlog không phải bài marketing mà gần với ghi chép nội bộ cho người trong cuộc, và Zig vẫn chưa phải 1.0
      PR có đầy đủ bối cảnh và căn cứ
      Khi đã chọn Zig thì coi như cũng chấp nhận một mức rủi ro thay đổi ngôn ngữ nhất định
      Ngược lại, dọn dẹp cho gọn gàng ngay từ bây giờ về lâu dài lại có lợi hơn
      (Cứ nghĩ đến những di sản không thể sửa được như thứ tự ưu tiên toán tử bit của C là hiểu)
    • mlugg là người đóng góp cốt lõi của Zig và cũng là thành viên Zig Foundation
      Thay đổi lần này nhằm giải quyết phụ thuộc vòng và sắp xếp lại hệ thống kiểu
      Các đề xuất liên quan đã được công khai ở #3257#15909
      Nhờ thay đổi này, quá trình phân giải kiểu của Zig được tổ chức thành cấu trúc DAG (đồ thị có hướng không chu trình), giúp độ ổn định của trình biên dịch tăng lên đáng kể
      Zig được vận hành theo mô hình BDFN (Benevolent Dictator For Now), với quyền quyết định cuối cùng thuộc về Andrew Kelley
      Tuy vậy đội ngũ là một tổ chức phi lợi nhuận và luôn đặt niềm tin của người dùng và chất lượng ngôn ngữ lên hàng đầu
      Cá nhân tôi thấy được làm việc cùng Matthew là một vinh dự lớn
    • Có lẽ thái độ như vậy phần nào là kết quả của việc lấy lịch sử hỗn loạn của ngôn ngữ C làm bài học phản diện
      Nó gợi nhớ đến C — một ngôn ngữ trên danh nghĩa thì chặt chẽ, nhưng thực tế lại là một mớ hỗn độn