1 điểm bởi GN⁺ 2025-10-17 | 1 bình luận | Chia sẻ qua WhatsApp
  • 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ểucả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 CNRSRemote
  • 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

 
GN⁺ 2025-10-17
Ý 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

    • Trong các ngôn ngữ lớn, chỉ nghĩ ngay ra các trường hợp hệ sinh thái bị phân mảnh vì thay đổi lớn như Python 3 và Perl 6; vì cú chuyển của hai ngôn ngữ này quá mạnh nên có lẽ những thay đổi ở ngôn ngữ khác cũng dễ bị cảm nhận là rất lớn
    • Với Elixir, không có cảm giác lúc nào cũng bị thúc ép phải chạy theo việc nâng cấp phiên bản; thay vào đó có thể xem các thay đổi mới được đưa vào và rồi tự thấy muốn nâng cấp vì có những tính năng mới đáng dùng; không thấy bất an hay căng thẳng như khi bị buộc phải đổi phiên bản theo kiểu bị kéo lê đi
    • Đã dùng Elixir trong môi trường production từ năm 2017, và mỗi lần nâng cấp đều diễn ra mượt hơn nhiều so với kỳ vọng; trái lại, các lần nâng cấp Erlang/OTP thường phức tạp hơn do vấn đề tương thích, nên thường vẫn dùng Elixir mới nhất nhưng đợi thêm một hai tháng mới nâng cấp OTP, sau khi các yếu tố xung đột đã được xử lý
    • Elixir vẫn còn hơi thiếu hoàn thiện và chưa đủ tiện dụng, nên cần có hướng dẫn rõ ràng hơn để đạt mục tiêu cũng như cần hệ sinh thái ổn định hơn; nhiều package bị bỏ hoang hoặc tài liệu còn thiếu nên khó theo kịp tốc độ thay đổi của hệ sinh thái Phoenix; cũng có nhiều người không muốn dùng LiveViews hay một số hệ thống component nhất định, và rào cản để tương thích với công cụ hay công nghệ khác còn cao; Python 3 thì việc chuyển từ 2 sang 3 là điều bắt buộc và đã làm khá tốt nhờ các công cụ migration tự động, dù cũng có nhiều lần thử-sai; trong khi đó Ruby 3 lại gây thêm rối vì đưa vào file kiểu bên ngoài và làm phân mảnh công cụ, cộng thêm boilerplate, vấn đề governance, gem bị chiếm đoạt... khiến trải nghiệm trở nên tiêu cực và bản thân không còn dùng Ruby nhiều nữa; nhấn mạnh rằng dù ngôn ngữ có tuyệt vời đến đâu thì cách điều hành non nớt cũng có thể phá hỏng mọi thứ, nên sự hợp tác và giao tiếp chín chắn cùng quản lý thay đổi tốt là rất quan trọng; cho rằng các thay đổi trong thiết kế ngôn ngữ cần được thử nghiệm trước đủ kỹ, thực hiện cẩn trọng, và thông báo sớm đầy đủ cho người dùng để giảm tối đa hỗn loạn không cần thiết; hy vọng Elixir/Phoenix/OTP sẽ ngày càng dễ dùng, mạnh mẽ, năng suất, hiệu năng tốt hơn để nhiều nhóm người dùng có thể yên tâm sử dụng; cũng gợi ý các tài nguyên như LivebookExercism Elixir track
  • 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

    • Vì muốn dùng Elixir mà đã nghỉ việc ở công ty để tự mình khởi nghiệp
  • 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_COUNT như sau

    PARTITION_COUNT=1:  12.336초 (유저 32.30s, 시스템 7.23s, CPU 320%)
    PARTITION_COUNT=5:  6.970초 (유저 0.37s, 시스템 0.49s, CPU 12%)
    PARTITION_COUNT=10: 7.236초 (유저 0.38s, 시스템 0.50s, CPU 12%)
    

    Mỗi lần đo ở giữa đều xóa cache bằng lệnh rm -rf _build

    • Có vẻ như các lần chạy sau được đo trong trạng thái cache đã có hiệu lực; có thể việc native compile đã diễn ra trực tiếp trong thư mục dep nên không để lại dấu vết trong _build
    • Không hiểu vì sao kết quả benchmark về tính năng của bản phát hành này lại bị downvote; muốn biết liệu ai đó có thể để lại ý kiến giải thích hay không
  • Trong 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

    • Điều kiện ở đây khác TypeScript; nhờ pattern matching mà ngay cả codebase Elixir hiện có cũng có thể suy luận kiểu được ít nhất khoảng 50%, và vì Elixir thuần sẽ cung cấp type như một phần mặc định nên những phần code còn được bảo trì có lẽ sẽ nhanh chóng được type hóa; bản thân tôi không thích hệ thống kiểu và chỉ dùng JS, nhưng với Elixir việc áp dụng type diễn ra tự nhiên; TypeScript thì đi theo hướng từ trên xuống, còn Elixir là môi trường nơi type lan truyền tự nhiên từ dưới lên
    • Gleam không thể tận dụng trọn vẹn các thế mạnh thực sự của OTP/BEAM; đó là sức hút mà chỉ Elixir mới mang lại
    • Elixir từ trước đến nay đã có sẵn các khái niệm về kiểu như primitive type, struct, destructuring dựa trên shape; cũng có thể kiểm tra kiểu bằng các công cụ như Dialyzer, TypedStruct; không phải là một ngôn ngữ vô kiểu phi lý như JavaScript
    • Gleam cũng tốt, nhưng trên JVM thì Kotlin là một ngôn ngữ có kiểu với cú pháp khá giống Ruby, và cũng có thể compile sang JS
  • 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”

    • Kotlin gần như đúng là cảm giác jruby mà chúng ta thực sự từng mong muốn
  • Đ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