Tập 32: Toán tử `?` — Quyền được thất bại gọn gàng

Hệ kiểu nghiêm khắc với Result mang lại sự an toàn tuyệt vời, nhưng nó nhanh chóng đòi "tiền tip" bằng sự rườm rà. Viết đi viết lại cấu trúc:

let val = match do_something() {
  Ok(v) => v,
  Err(e) => return Err(e)
}

chỉ sau vài hàm sẽ khiến ngón tay của lập trình viên đình công. DX (Developer Experience) không phải là chuyện chiều chuộng sự lười biếng; DX tồi chính là nguyên nhân chính khiến người ta tìm cách bypass các cơ chế an toàn của ngôn ngữ để viết code cho nhanh. Nếu một ngôn ngữ quá khó chịu để viết đúng, người ta sẽ tìm cách viết sai.

Giải pháp của DUY là postfix ? operator.

let val = do_something()?;

Sprint 34 đặt ra nhiệm vụ hiện thực hóa toán tử này. Về mặt kiến trúc, ? là một dạng cú pháp ngọt ngào (syntactic sugar) được hạ đường (lower) trực tiếp từ AST sang một biểu thức match chuẩn trước khi đi vào type checker. Nhưng "ngọt ngào" ở bề mặt thường đồng nghĩa với "cay đắng" ở bên dưới.

Khi compiler thay thế một nút ? trong AST bằng một cấu trúc rẽ nhánh phức tạp có chứa biểu thức return, nó phải đảm bảo scope của lệnh return đó thuộc về hàm chứa nó, chứ không phải một closure hay block con ẩn danh. Nếu một hàm không khai báo return type là Result mà lại dùng ?, compiler phải từ chối ngay lập tức kèm thông báo chỉ rõ kiểu trả về không tương thích.

Tôi đã mất cả một ngày Chủ Nhật chỉ để sửa một bug trong đó toán tử ? khi lồng trong một block rẽ nhánh phức tạp lại sinh ra mã trung gian nhảy sai nhãn. Chương trình C backend dịch ra bị lỗi cú pháp biến tạm không được định nghĩa. Đây là lúc tôi hiểu rằng mọi phép biến đổi AST ngầm đều phải trả giá bằng việc bảo tồn thông tin vị trí (source span preservation). Mỗi nút AST mới được sinh ra từ phép lowering phải mang theo DNA của dấu ? ban đầu.

Toán tử ? dạy tôi rằng an toàn và tiện dụng không cần phải là hai thế giới thù địch. Nhưng để chúng sống chung, compiler phải gánh phần việc nặng nhất: tự phân rã cú pháp đẹp thành semantics nghiêm cẩn mà không làm mất dấu vết nguồn gốc của lỗi.


Bình luận (0)

Đang tải bình luận...