2 điểm bởi GN⁺ 2025-07-11 | 1 bình luận | Chia sẻ qua WhatsApp
  • Flix là một ngôn ngữ đột phá kết hợp lập trình hàm với mô hình định hướng hiệu ứng
  • Ngôn ngữ này giúp mô hình hóa các quy tắc logic và phụ thuộc dữ liệu một cách dễ dàng, đồng thời có thế mạnh ở việc biểu diễn tri thức theo hướng khai báo
  • Có thể viết mã ngắn gọn để mô tả quan hệ phụ thuộc phức tạp và luồng quy trình
  • Cách tiếp cận này mang lại hiệu quả cho các tác vụ thiết kế thuật toán và suy luận
  • Thông qua tính năng truy vấn, có thể khám phá dữ liệu nền tảng tri thức một cách dễ dàng

Tổng quan về ngôn ngữ Flix

  • Flix là một ngôn ngữ hàm mới giới thiệu mô hình lập trình định hướng hiệu ứng
  • Lập trình viên có thể mô tả hệ thống xoay quanh các quan hệ và quy tắc logic, thay vì mã thủ tục
  • Bằng các quy tắc logic (được khai báo trong #{}), có thể biểu diễn ngắn gọn các kịch bản sản xuất phức tạp như thành phần, phụ thuộc, thời gian lắp ráp, thời hạn giao hàng

Quy tắc khai báo và mô hình dữ liệu

  • Trong ví dụ mã, các sự kiện và quy tắc như PartDepends, AssemblyTime, DeliveryDate, ReadyDate được sử dụng
    • Định nghĩa quan hệ phụ thuộc giữa các sản phẩm như PartDepends("Car", "Chassis")
    • Thiết lập thời gian lắp ráp theo từng bộ phận như AssemblyTime("Engine", 2)
    • Đồng thời chỉ rõ thời hạn giao hàng của bộ phận như DeliveryDate("Piston"; 1)
  • Thông qua quy tắc logic ReadyDate, có thể tính ra ngày sẵn sàng cuối cùng của các bộ phận có ngày giao hàng xác định hoặc các bộ phận dạng lắp ráp
  • Nói cách khác, có thể suy luận đơn giản về chu kỳ cung ứng và lắp ráp của từng bộ phận

Suy luận định hướng hiệu ứng và truy vấn

  • Bộ máy quy tắc logic của Flix kết hợp định hướng hiệu ứng với tính trong suốt tham chiếu, từ đó thúc đẩy thiết kế chương trình trực quan hơn và ít lỗi hơn
  • Sử dụng cú pháp truy vấn để dễ dàng rút ra ngày sẵn sàng của mọi bộ phận tương ứng với ReadyDate
  • Cách làm này có thể được ứng dụng trong nhiều lĩnh vực như sản xuất, quản lý chuỗi cung ứng, tự động hóa dựa trên suy luận

Tổng kết và ưu điểm

  • Flix kết hợp Effects với suy luận dựa trên quy tắc logic để mô hình hóa ngắn gọn mối quan hệ giữa các thành phần và quy trình trong những hệ thống phức tạp
  • So với các ngôn ngữ hiện có, nó có những ưu điểm khác biệt về độ rõ ràng logic và tính ngắn gọn của mã
  • Có thể cung cấp lời giải phù hợp cho nhiều bài toán phần mềm hiện đại như đồ thị tri thức, workflow engine, suy luận dữ liệu

1 bình luận

 
GN⁺ 2025-07-11
Ý kiến trên Hacker News
  • Tôi thực sự ấn tượng với chiều sâu và độ rộng của ngôn ngữ này
    Các tính năng thiết yếu như kiểu dữ liệu đại số, lập trình logic, tính biến đổi đều đã được tích hợp ngay từ đầu
    Điều tôi thích nhất khi nhìn vào bảng so sánh là một tệp thực thi duy nhất đảm nhiệm luôn vai trò package manager, LSP và compiler
    Với Haskell, LSP phải tái triển khai khá nhiều thứ giữa ghc và các tệp cabal, lại còn có cả stack được dùng nên tính “chính thống” của package manager cũng hơi mơ hồ
    Không phải tôi định chê Haskell, đó thực sự là một ngôn ngữ tuyệt vời
    Nhưng thật tiếc là những tính năng tốt nhất của nó dường như hơi bị ẩn đi
    Tôi tò mò không biết Flix tích hợp với Java và các ngôn ngữ khác trên JVM thuận tiện đến mức nào
    Vì compiler JVM xóa bỏ phần lớn thông tin kiểu, nên tôi thấy tích cực ở chỗ khái niệm regions của Flix hỗ trợ tương tác mệnh lệnh như một công dân hạng nhất
    Dùng JVM là một lợi thế cực lớn vì có thể dễ dàng tận dụng các thư viện chuẩn chất lượng cao trị giá hàng chục tỷ đô la
    Vì thế tôi nghĩ JVM hay .net core là lựa chọn hợp lý nhất cho hơn 90% dự án
    Có vẻ F# là ngôn ngữ duy nhất đáng đem ra so sánh
    Sẽ thật tuyệt nếu có một tài liệu tổng hợp các giới hạn trong khả năng tương tác giữa Flix và JVM
    Nhân tiện, có thông tin liên quan ở đây
    Về cơ bản, các giá trị Flix/Java đi qua quá trình boxing/unboxing
    Ngoài ra, Record cũng là công dân hạng nhất

    • Nếu bạn thích việc package manager, LSP và compiler đều là một tệp thực thi duy nhất, có lẽ bạn cũng sẽ rất thích Unison

    • Phần lập trình logic và datalog có cảm giác hơi được thêm vào
      Những tính năng khác thì rõ ràng giúp tăng tính an toàn kiểu của codebase, còn lập trình logic lại khá là tính năng dành cho số ít, nên tôi nghĩ có lẽ tốt hơn nếu nó tồn tại tách biệt với bản thân ngôn ngữ

    • Nói rằng compiler JVM xóa toàn bộ thông tin kiểu thì không hoàn toàn đúng đâu (với lớp ẩn danh thì tham số kiểu vẫn được giữ lại)
      Cũng có nhiều cách lách khác nhau
      Và thật ra từ góc nhìn của compiler thì đây không phải vấn đề lớn
      Chỉ cần ngẫu nhiên hóa tên lớp đã áp dụng type constructor rồi render nó như lớp bình thường là được

    • F# (vẫn) chưa hỗ trợ type class nên có khá nhiều hạn chế với lập trình dựa trên monad
      Nếu F# bỏ qua monad kiểu Haskell và nhảy thẳng sang algebraic effects thì theo tôi điều đó sẽ hợp hơn với triết lý của F#

    • Phần StringBuilder hơi khiến tôi thất vọng
      Ở khía cạnh này có vẻ nó nghiêng về phía Java hơn một chút nên tôi chưa thực sự bị thuyết phục
      Còn những phần khác thì nhìn qua thấy khá ổn

  • Xét từ góc độ ngữ nghĩa ngôn ngữ, có vẻ ngữ nghĩa mở rộng/hạn chế của record đa hình đang đi theo cách scoped label của Leijen (liên kết bài báo)
    Ví dụ nếu có record r1 = { color = "yellow" } thì có thể mở rộng thành r2 = { +color = "red" | r1 }
    r2#color sẽ cho ra "red", rồi nếu lại bỏ trường "color" đi thì r3 = { -color | r2 }
    r3#color sẽ cho ra giá trị gốc là "yellow"
    Tôi nghĩ cách này hợp lý hơn nhiều so với kiểu cũ, tức là dùng một hệ kiểu cực kỳ phức tạp chỉ để cấm thêm cùng một label field hai lần

  • Tôi tò mò vì sao Aarhus (đặc biệt là trường đại học/tech hub ở đó) lại có ảnh hưởng mạnh đến nghiên cứu ngôn ngữ lập trình như vậy
    C++, C#/Typescript, Dart đều có gốc rễ rất mạnh ở khu vực nhỏ bé này của Đan Mạch
    Nó không phải kiểu trường danh tiếng Ivy League hay Oxbridge điển hình như Delft hay INRIA
    Điều gì đã khiến nơi đó trở nên đặc biệt như vậy? Chỉ là tò mò vu vơ thôi, do nước chăng, hay vì lý do nào khác?

    • Nhắc một chút thì C# do Anders Hejlsberg tạo ra và ông ấy học ở DTU (Copenhagen)
      Turbo Pascal cũng do ông ấy làm, còn Borland là công ty do một người Đan Mạch sáng lập
      Nhìn chung Đan Mạch rất mạnh về lý thuyết ngôn ngữ lập trình
      Ví dụ, giáo trình cao học tiêu chuẩn trong lĩnh vực phân tích chương trình tĩnh (của Nielson & Nielson) cũng do người Đan Mạch viết
      Mads Tofte có đóng góp lớn cho Standard ML
      Aarhus có thể không ở đẳng cấp Ivy League hay Oxbridge, nhưng vẫn là một trường đại học xuất sắc
      Ở châu Âu có hàng chục trường kiểu như vậy: danh tiếng không quá lớn nhưng chất lượng giảng dạy và nghiên cứu rất cao

    • Aarhus có truyền thống rất mạnh trong logic, type theory, và các ngôn ngữ hàm/hướng đối tượng
      Nhiều nhà nghiên cứu có ảnh hưởng trong lĩnh vực này đều xuất thân từ Aarhus
      Ngoài ra, tôi cũng cảm thấy nghiên cứu ngôn ngữ lập trình trên toàn cầu bị lệch về phía Mỹ khá mạnh
      Những tổ chức như Aarhus thường rất ít làm marketing hay tự PR, và thiên về tập trung vào nghiên cứu tốt
      Không hẳn là tốt hơn hay kém hơn, nhưng điều đó khiến họ khó nhận được sự chú ý trên phạm vi toàn cầu hơn

  • Flix tiếp tục gây ấn tượng như ngôn ngữ được thiết kế chỉn chu nhất trong họ ML mà tôi từng thấy
    Sự kết hợp giữa các mô hình hàm, mệnh lệnh, logic cùng với hệ kiểu & hiệu ứng đa hình và cả các ràng buộc Datalog như công dân hạng nhất là điều thực sự độc đáo
    Việc phân tách nghiêm ngặt mã thuần/không thuần ở cấp kiểu mang lại cảm giác mới mẻ như một lựa chọn thay thế monad nhưng dễ suy luận hiệu ứng hơn
    Triết lý “một ngôn ngữ, không cần cờ” và việc chỉ hướng đến lỗi ở thời điểm biên dịch cũng đơn giản, dễ đoán và rất đáng thích
    Dù bản thân JVM không hỗ trợ loại bỏ đệ quy đuôi một cách native, việc Flix vẫn triển khai được loại bỏ lời gọi đuôi hoàn chỉnh là một thành tựu kỹ thuật đáng chú ý
    Tôi rất muốn nghe trải nghiệm từ những ai đang dùng Flix trong môi trường production hoặc nghiên cứu
    Đặc biệt là khi dùng trong lập trình logic hay đồng thời, mọi người đã gặp khó khăn gì với “closed-world assumption”, việc không hỗ trợ exception, hay sự khác biệt giữa tích hợp Datalog và các ngôn ngữ logic khác như Prolog?

  • Hồi trước tôi từng xem qua Flix và thấy rất thú vị, đến mức còn viết một bài có tiêu đề “Flix for Java Programmers”
    Giờ nó hơi cũ nên chắc cần cập nhật lại một chút...
    Nếu ai quan tâm thì có thể xem ở đây

    • Bài blog thật sự rất hay
      Nếu được phép thì sẽ rất tuyệt nếu thêm nó vào tuyển tập blog chính thức của Flix (liên kết)
      Từ sau bài đó, ngôn ngữ Flix đã phát triển khá nhiều
      Đặc biệt là hệ hiệu ứng đã được mở rộng mạnh, khả năng tương tác Java được cải thiện và cú pháp cũng đã được cập nhật

    • Blog đúng là như một kho báu
      Nó giống như phiên bản tinh tế hơn của những suy nghĩ đã làm tôi bận tâm suốt thời gian dài
      Tôi rất háo hức đọc hết tất cả

  • Hỗ trợ cả HKT nên rất tuyệt
    Nhưng tôi không thấy giải thích gì về typeclass nên khá tò mò
    Nếu chỉ cần hỗ trợ thêm typeclass và macro kiểu Scala thì tôi có thể sẽ thử chuyển các thư viện tôi viết (distage, izumi-reflect, BIO) sang Flix, và nghiêm túc cân nhắc chuyển từ Scala sang Flix
    Sau đó tôi phát hiện ra rằng về sau họ gọi typeclass là traits
    Tôi cũng tò mò macro thì sao
    Ngoài ra tôi thấy hơi tiếc là Flix cũng không hỗ trợ nominal inheritance tường minh
    Thành ra ngay cả dạng trait vô hại nhất của Scala cũng không được phép
    Tôi cảm thấy typeclass không thể thay thế interface, và nếu không có lớp trừu tượng đó thì rất nhiều thứ hữu ích либо không thể triển khai được, либо mã sẽ trở nên xấu xí

    • Flix hỗ trợ typeclass (ở đây gọi là trait) cùng với HKT, associated type và associated effect
      Trait cũng có thể cung cấp triển khai mặc định cho hàm, nhưng instance có thể override
      Flix hoàn toàn không có inheritance
      Trait chỉ được dùng ở thời điểm biên dịch và đi qua quá trình monomorphization nên không có chi phí runtime
      Trình inliner của Flix cũng tối ưu cả bên trong trait, đến mức tích cực loại bỏ luôn closure
      Ví dụ các hàm bậc cao hay pipeline ở mức bytecode sẽ biến thành các vòng lặp bình thường, không còn allocation cho closure hay gián tiếp tham chiếu gì cả
      Flix hiện vẫn chưa hỗ trợ macro
      Có lẽ vì kinh nghiệm (bị lạm dụng) ở các ngôn ngữ khác nên họ ngại đưa vào
      Bọn tôi đang tìm thêm tác giả thư viện mới, nên nếu hứng thú thì mong bạn ghé qua kênh Gitter
  • Liên quan đến mục “các tính năng Flix không hỗ trợ” trong tài liệu chính thức
    Có một mục là No Code Before Main
    Nhưng phần mô tả thực tế lại là “Flix không chạy bất kỳ đoạn mã nào trước main, hoàn toàn không có static initializer hay thứ tương tự”
    Tôi nghĩ tên tính năng nên đổi thành Code Before Main thì sẽ chính xác hơn

  • Tôi tò mò vì sao trong Flix lại bắt buộc phải đánh dấu tường minh việc một hàm là thuần
    Gần như trong mọi trường hợp, có vẻ phân tích tĩnh là đủ để suy luận, nên tôi muốn biết lý do là gì

    • Theo tôi biết thì nếu bạn đánh dấu tính thuần cho hàm, compiler sẽ đảm bảo điều đó cho bạn

    • Khi nhìn vào câu “Flix tracks the purity of every expression in the program exactly”, cùng với ví dụ định nghĩa hàm không có ký hiệu thuần/không thuần
      thì có vẻ trong đa số trường hợp compiler hoàn toàn có thể tự suy luận tính thuần
      nên tôi có cảm giác việc đánh dấu thuần/không thuần có thể chỉ là tùy chọn

  • FAQ của Flix (liên kết) mở đầu khá bình thường nhưng càng đọc càng buồn cười
    Một vài ví dụ hài hước:

    • Hỏi: Chia cho 0 thì kết quả thật sự là 0 à?<br> Đáp: Đúng. Nhưng chỉ chăm chăm vào chuyện này cũng giống như chỉ quan tâm màu ghế trên tàu vũ trụ vậy
    • Hỏi: “Trang này cần JavaScript”<br> Đáp: Những người chỉ trích việc dùng JavaScript: [1],[2],[3],[4],[5], số người thực sự đề nghị giúp refactor sang HTML: 0
    • Hỏi: Tôi thất vọng vì có tính năng X thay vì tính năng Y mà tôi thích<br> Đáp: Rất tiếc
    • Hỏi: Đây là cú pháp tệ nhất trong mọi ngôn ngữ hàm tôi từng thấy. Semicolon, dấu ngoặc nhọn và một mớ ký hiệu đâm sầm vào nhau. Cứ như Scala, Java và Haskell đã có một đêm tình một lần ngay giữa Chernobyl vậy<br> Đáp: Như thế chẳng phải là một thành tựu đáng nể sao?
  • Tôi tò mò liệu các code agent tương thích với ngôn ngữ này có hoạt động tốt không, hay vẫn là tình huống phải tự mình vắt óc
    Nói đùa vậy thôi, nhưng thật sự nhìn ngôn ngữ này rất hay nên cũng thấy buồn
    LLM có lẽ sẽ càng cản trở việc chấp nhận các ngôn ngữ mới, và tôi tự hỏi vấn đề này sẽ được giải như thế nào

    • Tôi lại có trực giác rằng LLM sẽ làm giảm rào cản tiếp nhận ngôn ngữ mới
      Mã của thư viện chuẩn là đủ để LLM học cú pháp mới, mà kể cả không đủ thì agent vẫn có thể quan sát đầu ra compiler để học dần
      Bản thân việc chuyển mã không phải loại công việc đòi hỏi sáng tạo cao, mà là một việc được xác định khá rõ, nên nó sẽ là một trong những lĩnh vực tự động hóa đầu tiên của LLM
      Về sau, tôi nghĩ phần chúng ta thật sự phải dùng đầu óc nghiêm túc suy nghĩ sẽ là “vì sao ta làm việc này” và “nó tạo ra tác động gì lên thế giới”

    • Tôi nhận được kết quả khá ổn khi ghi rõ trong prompt rằng bắt buộc phải dùng index/dependent types của Idris
      (nếu không có chỉ dẫn kiểu đó thì thường cùng lắm chỉ ra được GADT)