- Phiên bản Elixir 1.19 cho phép phát hiện nhiều lỗi hơn và nhanh hơn nhờ củng cố hệ thống kiểu và cải thiện hiệu năng biên dịch
- Suy luận kiểu được mở rộng tới hàm ẩn danh và protocol, giúp tự động kiểm chứng trên phạm vi rộng hơn mà không cần chú thích kiểu từ người dùng
- Trên các dự án lớn, phiên bản này mang lại tốc độ biên dịch nhanh hơn tới 4 lần, bao gồm tối ưu biên dịch song song và nạp mã
- Hệ sinh thái và độ minh bạch chuỗi cung ứng cũng được tăng cường với hỗ trợ Erlang/OTP 28 và áp dụng chứng nhận OpenChain
- Ngoài ra còn có nhiều tính năng khác như cải thiện phân tích tùy chọn, nâng cao khả năng gỡ lỗi của ExUnit và cải thiện khả năng truy cập tài liệu dựa trên shell
Các cải tiến chính của Elixir 1.19
Cải tiến hệ thống kiểu
Suy luận kiểu cho mọi thành phần
- Type inference (suy luận kiểu) là tính năng tự động xác định kiểu của biểu thức tại thời điểm biên dịch
- Trước đây, hệ thống chủ yếu hướng tới hỗ trợ suy luận kiểu cho pattern, guard và giá trị trả về, nhưng ở bản phát hành này đã đưa vào suy luận kiểu cho mọi thành phần (trừ guard)
- Kiểu cũng được suy ra bằng cách tham chiếu đến các lời gọi trong module và các hàm của thư viện chuẩn Elixir, nên những hàm trước đây bị suy ra là
dynamic() -> boolean() giờ có thể được suy ra rõ ràng hơn như integer() -> boolean()
- Suy luận kiểu đi kèm nhiều đánh đổi như tốc độ biên dịch, khả năng biểu đạt, biên dịch tăng dần và độ rõ ràng của lỗi, vì vậy trong tương lai sẽ tiếp tục bổ sung suy luận kiểu cho guard và thông tin kiểu của dependency
- Nếu hàm có khai báo type signature rõ ràng, hệ thống sẽ hoạt động theo cơ chế kiểm tra kiểu tường minh thay vì suy luận kiểu, chỉ cho phép các kiểu phù hợp với chú thích của người dùng
Kiểm tra kiểu khi dispatch và triển khai protocol
- Elixir giờ đây áp dụng kiểm tra kiểu khi gọi và triển khai protocol
- Ví dụ, nếu truyền vào nội suy chuỗi một kiểu không triển khai protocol
String.Chars, hệ thống sẽ đưa ra cảnh báo
- Trong for comprehension, nếu truyền một kiểu không thỏa mãn protocol
Enumerable làm generator thì cũng sẽ phát sinh cảnh báo
- Nhờ các kiểm tra kiểu này, có thể ngăn chặn thêm nhiều lỗi ngay từ thời điểm biên dịch
Suy luận và kiểm tra kiểu cho hàm ẩn danh
- Elixir 1.19 hỗ trợ suy luận kiểu và kiểm tra kiểu cho hàm ẩn danh
- Chẳng hạn, nếu truyền một kiểu sai như
"hello" vào hàm ẩn danh đang kỳ vọng kiểu %{}, hệ thống có thể phát hiện ngay bằng cảnh báo lúc biên dịch
- Suy luận kiểu cũng được áp dụng cho function capture (
&String.to_integer/1 v.v.), giúp mở rộng phạm vi kiểm chứng kiểu tự động
Tham khảo và đối tác
- Hệ thống kiểu này được phát triển thông qua quan hệ hợp tác giữa CNRS và Remote
- Fresha, *Starfish* *, Dashbit cùng một số bên khác đã tài trợ
Tốc độ biên dịch nhanh hơn trên các dự án lớn
Cải thiện nút thắt nạp mã
- Trước đây, module được nạp ngay khi được định nghĩa, nhưng ở bản phát hành này chiến lược đã được đổi sang lazy loading
- Nhờ vậy, giảm tải cho code server và cải thiện hiệu năng biên dịch song song, giúp tốc độ biên dịch trên dự án lớn tăng hơn 2 lần
- Hai điểm cần lưu ý chính
- Nếu trong lúc biên dịch tạo tiến trình riêng để truy cập module trong cùng dự án, có thể xảy ra thiếu nạp; để xử lý, có thể dùng
Kernel.ParallelCompiler.pmap/2 hoặc Code.ensure_compiled!/1
- Khi gọi module trong cùng dự án bên trong callback
@on_load, có thể phát sinh lỗi; khi cần có thể dùng tùy chọn @compile {:autoload, true}
- Cả hai trường hợp này trước đây đều có thể gây ra lỗi biên dịch không xác định, nhưng cải tiến lần này giúp đảm bảo môi trường biên dịch mang tính xác định (có thể tái hiện)
Biên dịch song song dependency
- Hỗ trợ biên dịch song song dependency thông qua biến môi trường
MIX_OS_DEPS_COMPILE_PARTITION_COUNT
- Do có thể tận dụng đồng thời nhiều tiến trình hệ điều hành để biên dịch dependency song song, hiệu năng biên dịch có thể cải thiện tới 4 lần tùy theo quy mô dự án và số lõi CPU
- Về thực nghiệm, việc đặt giá trị khoảng một nửa tổng số lõi thường hiệu quả trong sử dụng tài nguyên
- Vì song song hóa có thể làm tăng mức sử dụng bộ nhớ, nên cần lưu ý khi áp dụng trên CI hoặc máy chủ build
Hỗ trợ Erlang/OTP 28
- Elixir 1.19 chính thức hỗ trợ Erlang/OTP 28.1+
- Theo thay đổi trong cách biểu diễn biểu thức chính quy ở Erlang/OTP 28, không còn có thể dùng biểu thức chính quy làm giá trị mặc định của struct
- Khi khởi tạo struct, vẫn có thể tiếp tục dùng biểu thức chính quy
Áp dụng chứng nhận OpenChain
- Đây là phiên bản đầu tiên bắt đầu tuân thủ tiêu chuẩn OpenChain
- Mỗi bản phát hành sẽ bao gồm SBoM (Source Bill of Materials) theo định dạng CycloneDX 1.6/SPDX 2.3
- Điều này giúp nâng cao độ minh bạch chuỗi cung ứng đối với các thành phần và giấy phép trong bản phát hành, đồng thời hỗ trợ quản lý chặt chẽ hơn
- Công việc này do Jonatan Männchen thực hiện, với sự tài trợ từ Erlang Ecosystem Foundation
Các cải tiến khác
- Nhiều cải tiến cho công cụ và thư viện đã được bổ sung, bao gồm phân tích tùy chọn, khả năng gỡ lỗi và hiệu năng của ExUnit, cũng như khả năng truy cập tài liệu dựa trên shell
- Để biết ghi chú phát hành chi tiết hơn, hãy tham khảo CHANGELOG
1 bình luận
Ý kiến Hacker News
Nhấn mạnh rằng cách Elixir dần dần đưa tính năng kiểm tra kiểu tự động vào là một ví dụ cải tiến ngôn ngữ rất đáng để các ngôn ngữ lập trình khác học hỏi; đã có nhiều trường hợp ngôn ngữ bị chia đôi hệ sinh thái vì những thay đổi quá lớn, còn với Elixir thì từ năm 2018 José đã nói rất rõ rằng bản thân ngôn ngữ đã hoàn thiện, nên khá yên tâm; ngôn ngữ và phần lõi sẽ không còn bị phá vỡ nữa, tạo cảm giác rất ổn định; cũng đề xuất video bài nói liên quan; cảm thấy rất ấn tượng với cách vận hành nhất quán và xuất sắc
Elixir đang phát triển ổn định khi liên tục đưa ra những tính năng và cải tiến rất tốt; cấu trúc ngôn ngữ rất xuất sắc và những người tạo ra nó liên tục giữ được định hướng đúng đắn, điều này thật sự rất ấn tượng; ngược lại, điều đáng tiếc là không có nhiều cơ hội dùng Elixir trong công việc hằng ngày
Chia sẻ dữ liệu thử nghiệm về tốc độ biên dịch dependency của Phoenix; trên Mac M1 Max, với một ứng dụng nhỏ chỉ gồm các dependency mặc định của Phoenix, thời gian biên dịch đo được theo giá trị của biến môi trường
MIX_OS_DEPS_COMPILE_PARTITION_COUNTnhư sauMỗi lần đo ở giữa đều xóa cache bằng lệnh
rm -rf _build_buildTrong vài tháng gần đây đã thực sự thích Gleam; cũng rất hoan nghênh việc Elixir đưa vào hệ thống kiểu, nhưng trước đây chính điểm này từng là một trong những lý do lớn khiến khó chấp nhận Elixir; vẫn muốn một ngày nào đó thử lại Elixir, nhưng lo rằng nó có thể giống TypeScript ở chỗ chỉ có vẻ ngoài là typed, còn thực tế thì trong nhiều lib hay package lại chỉ thành dynamic/any; muốn biết liệu nỗi lo đó có phải là thừa hay không; Beam thực sự rất tuyệt
Cảm thấy Elixir là môi trường web có nhiều triển vọng nhất; mỗi lần gặp các tổ chức hay đội ngũ dùng Elixir trong công việc thực tế thì thấy mặt bằng năng lực của họ thường cao hơn mức phổ biến; nghĩ rằng trong môi trường cần phát triển liên tục, Elixir vẫn luôn đưa ra định hướng và tiêu chuẩn rõ ràng
Giới thiệu rằng bản phát hành Elixir đã bắt đầu hỗ trợ định dạng Source SBoM như CycloneDX 1.6 trở lên và SPDX 2.3 trở lên; thật sự đáng trân trọng khi việc quản lý SBOM được thực hiện ở cấp độ ngôn ngữ; tiếc là hiện tại công ty không dùng Elixir
Nếu muốn đóng góp cho một dự án Elixir mã nguồn mở đang được dùng thực tế, thì các thành phần cốt lõi trước đây của Mozilla Hubs vẫn đang tiếp tục được phát triển bằng Elixir dưới dạng các dự án độc lập; có thể tham khảo Hubs Foundation/reticulum
Dựa trên thư viện chuẩn Elixir, có thể suy luận kiểu ở thời điểm biên dịch cho các tình huống đặc thù của ứng dụng, chẳng hạn từ kiểu động sang boolean, hoặc từ integer sang boolean
Chưa có kinh nghiệm phát triển với Elixir nhưng là fan; trước đây thích tính thực dụng và vẻ đẹp của Ruby, nhưng sau khi thấy hấp dẫn với hệ thống kiểu thì đã đổi sang ngôn ngữ khác; cả Elixir và Ruby đều đã đưa vào hệ thống kiểu, nhưng hiện tại chủ yếu dùng Kotlin vì về mặt cú pháp nó mang cảm giác như một “Ruby có kiểu”
Đang dùng Soketi để kết nối với pusher sdk và xử lý broadcast sự kiện; ứng dụng có cấu trúc pha trộn giữa endpoint thời gian thực và endpoint REST, tải tính toán realtime không quá lớn nhưng nếu cần thì định tách riêng sang Go để xử lý; cũng sắp thêm tính năng cộng tác, nên đang phân vân liệu trong tình huống này có nên đưa Phoenix vào hay không